The Speech/Sound Cartridge talks, as long as the CoCo 3 slows down
With the clock mod out, the 6309 CoCo 3 stayed up long enough for me to finally give the Speech/Sound Cartridge a real try. It talks now. I wrote a small say command in 6809 assembly under NitrOS-9 that speaks whatever you type after it. The catch is that the CPU has to drop to slow speed while it speaks.

The Multi-Pak comes out
The SSC and the CoCo SDC both want the one cartridge slot, so the Multi-Pak finally earned its desk space. The SSC is in slot 1, the SDC is in slot 4, and the switch is on 4 so it still boots NitrOS-9 off the SDC.
| Address | Use |
|---|---|
$FF7E | Data and status. Bit 7 set means ready for a character. Write text and end with a CR ($0D) to speak. |
$FF7D | Reset, write 1 then 0 |
$FF01 / $FF03 | PIA0 CA2 low and CB2 high select the cartridge on the sound mux |
$FF23 | PIA1 CB2 high turns sound output on |
$FFD8 / $FFD9 | CoCo 3 CPU slow (0.89 MHz) or fast (1.79 MHz), any write |
At first the SSC looked stuck and say timed out. Resetting and reseating the cartridge is what got it going, and after that it assembled and ran. Old tech. I need to check the simple stuff like that first.
Speech is a faint blip at 1.79 MHz
NitrOS-9 runs the CoCo 3 in double speed. In fast mode the speech comes out as a faint blip. At slow speed it’s clear. From what I’ve read, the SSC’s op-amp gets its negative rail from the E clock, and that rail sags when the clock doubles. I haven’t measured it.
say drops the CPU to slow speed and leaves it there, because the SSC keeps talking after the program exits. When the speech is done, a BASIC09 procedure called fastmode puts it back.
say.asm
This assembles with the native OS-9 asm, which knows the 6309. The rma on the disk uses a different module syntax and only does 6809. I don’t use os9defs either. It fills up asm’s symbol table, and the os9defs.a on disk is rma style and leaves Prgrm, Objct and ReEnt undefined, so each program defines the few symbols it needs with equ.
nam say
* --- definitions (instead of os9defs) ---
Prgrm equ $10 module type: program
Objct equ $01 language: 6809 object code
ReEnt equ $80 attribute: reentrant
F$Exit equ $06 system call: exit process
rev set 1
tylg set Prgrm+Objct
atrv set ReEnt+rev
mod eom,name,tylg,atrv,start,size
* --- data area ---
org 0
stack rmb 200
size equ .
name fcs /say/
fcb 1 edition
* --- main: X -> command line, CR terminated ---
start sta >$FFD8 slow CPU to 0.89 MHz (any write works)
bsr sndon
loop lda ,x+ next character
bsr putc
cmpa #$0D sent the CR yet?
bne loop
clrb no error
os9 F$Exit
* --- send A to SSC, wait for ready (bit 7 set) ---
* --- gives up after 65536 tries, exits error 1 ---
putc pshs a,x
ldx #0
wait lda >$FF7E
bmi ready bit 7 set = ready
leax -1,x
bne wait
puls a,x
ldb #1 timeout
os9 F$Exit
ready puls a,x
sta >$FF7E
rts
* --- route cartridge audio to the TV ---
sndon lda >$FF01
anda #$C7 clear CA2 control bits
ora #$30 CA2 = output low
sta >$FF01
lda >$FF03
ora #$38 CB2 = output high
sta >$FF03
lda >$FF23
ora #$38 CB2 high = sound on
sta >$FF23
rts
emod
eom equ *
end
OS-9 hands the program X pointing at the command line, already terminated with a CR, which is exactly what the SSC wants. putc saves A and X, so the cmpa #$0D checks the character it just sent. sndon only touches bits 3 to 5 of each PIA control register, the same as the POKEs from BASIC. If the cartridge never goes ready, say exits with ERROR #001.
Getting better at BASIC09
BASIC09 has no immediate mode, so even a one-liner goes in a procedure. I wrote two small ones and packed them so they run from the shell.
cls clears the screen, because for some reason NitrOS-9 doesn’t come with a cls or clear. It just sends a form feed:
SHELL "display 0c"
fastmode puts the CPU back in fast mode after say leaves it slow:
POKE $FFD9,0
Things that tripped me up
- The shell only looks in memory and the execution directory for commands, never the data directory. I run work in progress by full path, like
/dd/dev/say/say HELLO HOW ARE YOU, instead of copying it into/dd/cmds. - A
loaded module stays in memory, so a rebuilt one needsunlinkfirst. - If a module won’t run,
attr sayshows whether it has theeattribute.
Still open
- Have
sayswitch back to fast on its own: after the CR, wait for bit 7 of$FF7Eagain and write$FFD9. Bit 7 only means ready for a character, so if speech gets cut off I need to find a real “done speaking” bit in the service manual. - Maybe an SSC device driver so
echo HELLO >/sscworks. - Maybe a cross-dev path with lwasm and ToolShed
os9 copyonto an SDC image.