Commodore‎ > ‎C128‎ > ‎SAM 128‎ > ‎


  Using Reciter 128 with the BASIC Wedge
This section explains using Reciter 128 in BASIC with the "wedge" installed, and is very easy to use.  (You may also use Reciter from ML or from BASIC without the "wedge", see below.)  See the main SAM 128 page for details about installing SAM+Reciter and the BASIC Wedge.

Note: If you have previously set BASIC into "SAM-Mode", then you need switch it back to "Reciter-Mode" with the BASIC-Wedge command:
]RECITER (if you want to use English text described on this page),
or else see the SAM page (if you want to use phonetic text instead).

Speaking English text is very easy, just enter the "SAY" command followed with a string expression.  Some examples:
]SAY "HELLO WORLD!" :REM constant string
]SAY A$ :REM scalar variable
]SAY T$(2) :REM array variable
]SAY LEFT$(X$,4)+"S." :REM general string expression

I hope you agree by the examples, that the syntax is simple and flexible.  Reciter will accept any string as valid text, but it should not contain any embedded ESC (code 27) or "shifted-escape" (code 27+128) characters.  Reciter will ignore anything which follows such characters.

Reciter will translate your English text into SAM's phonetic language (with about 95% "raw" accuracy).  Reciter will also translate some numbers and punctuation into spoken text [see Using Reciter (general), below].  "Raw" accuracy means the phonetic translation -- please note that even if the correct phonemes are used, Reciter may not sound "right" (true accuracy) because the correct stress is not used.  Proper stress is often context-dependent -- you may have to resort to SAM's phonetic mode if Reciter fails to give satisfactory results.  On the other hand, if the phonetic translation is wrong (5% error, due to so many exceptions in the English language), you can often alter the spelling (use wrong spelling) to get the right speech.

How do you know if the translation is correct?  I can only give a partial answer.  If a string spoken by Reciter doesn't sound right, then you can use the ERROR command to display the phonetic translation that Reciter used.  You would then have to decide if the translation is correct (which requires a good understanding of SAM's phonetic language).

For example, ask Reciter to say the phrase "The quick and easy way" like this:

You can then see the phonetic translation used by Reciter by entering ]ERROR.  Reciter will print the following:

That won't make any sense if you don't understand SAM's special phonetic language.  And you don't need to learn it, if you are happy with Reciter's default accent and pronunciation.  (See the page about Using SAM for more details.)

Besides stress, there are several ways you can alter Reciter's speech.  See the page about Common Routines.

   Using Reciter 128 with ML  
Note: This section may be useful to BASIC users who are not using the Wedge.

There are two ways to call Reciter 128 from a machine language (ML) / assembly language program.  The most common will probably be to call 'Reciter' at $EE0F (60943).  Before doing that, you will need to copy the phonetic text you want spoken into SAM's buffer.  Your text string should be terminated with an ESCape character: $1B (27).  If not, Reciter will say 'random' junk  after your desired text is spoken.  In the current (Epsilon) release, the buffer is located at $D800~$D8FF.  Because the buffer may move in later versions, you can find the buffer address in memory locations $EE22/23 (a word). 

Another method, which only applies if you are using BASIC variables, is to simply call 'ReSyBASIC' at $EE0C (60940).  Before calling this routine, you first need to have a string variable named SA$ defined.  If you don't, an empty string named SA$ will be created.  You don't need a special terminator byte in the string (because BASIC knows how long the string is).

Either way, your string should not have any embedded ESC ($1B) or 'shifted ESC' ($9B) character(s).  If it does, Reciter will ignore whatever follows (the first).

The following examples show the non-wedge BASIC calls to Reciter (i.e., ReSyBASIC at $EE0C).  So if you are using ML, just use a simple JSR if running in BANK 1 (unlikely) or else use JSR_FAR.  And ML user's that don't want to use BASIC strings must call 'Reciter' at $EE0F instead.

For example,

If you are using BASIC (without the Wedge), it saves a lot of typing (and reduces memory use and improves RUN speed) if you use a variable for the value 60940.  Also, you only need to use BANK 1 if you have used some other BANK command (or no BANK command) before using SYS.  Thus a more practical example is,

This assumes BANK 1 was the last BANK command issued, and variable AM = 60940. 

Below is an example in pure ML (you can enter it with the built-in MONITOR) which runs in BANK 15 at address $1300.  It is the same as above, except it does not rely on BASIC variables (and thus does a virtual SYS 60943 instead of SYS 60940 shown above):
.1300 LDA #0      ;use BANK 15 (for KERNAL routine $FF77)
.1302 STA $FF00
.1305 LDA #00     ;point to SAM buffer ($d800)
.1307 LDX #D8
.1309 STA $FE     ;pointer in $FE,$FF
.130B STX $FF
.130D LDA #$FE    ;where our pointer is
.130F STA $02B9   ;set for IND_STORE
.1312 LDY #$12    ;length of string (followed by $1b terminator)
;this loop copies string to SAM buffer
.1314 LDA $1330,Y ;read from current bank
.1317 LDX #1      ;select BANK 1
.1319 JSR $FF77   ;write to another bank
.131C DEY         ;count chars
.131D BPL $1314   ;loop until all copied
;now call Reciter at $ee0f
.131F LDX #1      ;run code in BANK 1
.1321 STX $02
.1323 LDA #$EE    ;address $EE0F
.1325 LDX #$0F
.1327 STA $03     ;set for JSR_FAR
.1329 STA $04
.132B JSR $02CD   ;call JSR_FAR
;your code continues...
.132E NOP
.132F RTS
;the text "ASSEMBLY LANGUAGE." + $1B
>01330 41 53 53 45 4D 42 4C 59 20 4C 41 4E 47 55 41 47
>01340 45 2E 9B
;test the example
J 1300

Note if you want to run in BANK 0 (instead of BANK 15), then the first LDA should have an argument of #$3E (MMU value for BANK 0), and inside the copy loop you should change "LDX #1 / JSR $FF77" to  "LDX #$7F / JSR $02AF" (load .X with the MMU value of BANK 1, and call "stash" code in Common RAM).

Another, uncommon, SYS command you may use with Reciter 128 is the Error Display call.  Reciter 128 will accept any text string, so you normally wouldn't call this!  However, a neat trick is you can call this routine, at 60949 ($EE15), after having Reciter speak, and it will list the phonetic text that Reciter produced  for SAM to speak.  This is a great way to learn more about SAM's phonetic language (and what Reciter is doing with your English text)!  So if you just executed the example above, then entering SYS 60949 would cause SAM to print:

That won't make any sense if you don't understand SAM's special phonetic language.  And you don't need to learn it, if you are happy with Reciter's default accent and pronunciation.  (See the page about Using SAM for more details.)

Note: even if you are not using BASIC at all, the MMU pre-configuration registers B (and possibly D) must be set to the same values used by BASIC ROM ($7F and $41, respectively).  The 'D' pre-configuration register is only used for finding the BASIC string SA$ and for printing the 'error' text (SAM translation).  In both these cases, the BASIC ROM must also be installed in the C128.  In the later case, the KERNAL ROM is also required.

   Using Reciter 128 (general)  
Reciter (128) will accept any text input.  It should not produce an error.  However, there is 'debug' code that will halt Reciter (and sound a 'Beep Beep') if Reciter is unable to translate your input text into SAM's phonetic language.  This should only happen if you are brave enough to attempt writing your own, custom Dictionary for Reciter.  As far as I can see, the included/default Dictionary covers every possible case and this should never happen.  (This does not mean the word will be pronounced correctly!)

Capitalization is ignored.  Any ASCII/PETSCII text will be transformed into upper-case ASCII at the beginning of Reciter.

Besides speaking English words, Reciter will also speak some punctuation marks and numbers. 

In regards to numbers, Reciter only 'knows' the cardinal numbers zero to nine!  As a special case, the dictionary also includes the translation for 64 (sixty-four)... guess why!  In this Beta release, I added another special case for 28 (twenty-eight)... guess why!  Thus if you ask Reciter to say "50"  (fifty), he will actually say "five-zero"!  Reciter also knows the ordinal numbers 1st to 10th (that is, "first" to "tenth").  If you try something else, like 21st (twenty-first), he will say "two-first"!

Reciter (like SAM) understands some punctuation marks as special (he will not try to say them):
Mark ASCII(hex) Name Effect

$20 space (ignore)
! $21 exclamation same as period "."
, $2C comma long pause in speech
- $2D dash short pause in speech (only if surrounded by spaces)
hyphen no pause in speech (otherwise)
. $2E period reduce pitch of previous phonemes, then (long) pause speech (if not followed by a digit)
: $3A colon same as period "."
; $3B semi-colon same as period "."
? $3F question mark reduce pitch of previous phonemes, then (long) pause speech
This is (mainly) just an 'enhanced' version of SAM's rules for punctuation.  However, there are three things different in Reciter (as opposed to "pure" SAM):
  • If a dot/period is followed by a number, then Reciter will not pause his speech, but will instead say the word "point"; for example, the string "1.5" will be spoken as "one point five" (without any pause).
  • A question mark (?) will render the final phonemes of a sentence with reduced pitch.  This is the opposite of SAM!  I can only guess -- the original documentation notes that only some questions should end with a rising pitch (only those which require a yes/no answer).  So I'm thinking Reciter is too stupid to know when a rising pitch is needed, and thus defaults to the "period" method (reduced pitch at end of sentence).
  • Reciter will normally ignore a "dash" (-).  For example, "TWENTY-ONE" will be spoken with no pause between "twenty" and "one".  However, if the dash is surrounded by spaces, Reciter will insert a short pause (like SAM).  For example, "YOU HAVE TWO CHOICES - FIGHT OR FLIGHT"

Most other non-alphanumeric characters will be ignored.  In particular, all the ASCII non-printing characters (except $1B and $9B) will be ignored.  However, Reciter will literally say the following marks:
Mark ASCII(hex) Name Reciter says
" $22 end quote UNQUOTE (if followed by any punctuation [like space])
begin quote QUOTE (otherwise)
# $23 octothorpe NUMBER
$ $24 dollar DOLLAR
% $25 percent PERCENT
& $26 ampersand AND
* $2A asterisk ASTERISK
+ $2B plus PLUS
. $2E period POINT (if followed by a digit)
/ $2F slash SLASH
< $3C less-than LESS THAN
= $3D equals EQUALS
> $3E greater-than GREATER THAN
^ $5E carrot CARROT
Note: the non-printing ASCII code "ESCape" ($1B) will halt Reciter input (all following characters will be ignored).  The 'extended-ASCII' code of $9B will do the same (this is the normal end-of-text marker for SAM and Reciter).

See also the page about Common Routines for ways to manipulate the sound of SAM and Reciter.

SAM (64) © Don't Ask, Inc., 1982
SAM 128 © H2Obsession, 2015
Webpage © H2Obsession, 2015, 2016