senior_falcon Posted December 27, 2018 Author Share Posted December 27, 2018 (edited) There is an interesting difference between speech in XB and speech with assembly. "TEXAS INSTRUMENTS" is a phrase in the speech synth's resident vocabulary. (Page 205 XB manual) 10 CALL SAY("TEXAS INSTRUMENTS") In XB this sounds out each letter: T E X A S I N S T R U M E N T S In assembly it says "texas instruments" Evidently XB takes it one word at a time, and neither TEXAS nor INSTRUMENTS is part of the synth's vocabulary. Here's a question for the assembly gurus. On page 350 of the E/A manual they show how to get a delay of 42 microseconds, but I think the delay is much longer than that. The TI99 runs at 3 mhz, so 3 clock cycles is one microsecond, so 42 microseconds is 126 clock cycles. You want to be sure that speech works if running on the 16 bit bus, so here is the program with the clock cycles if running on the 16 bit bus: BL @DLY42 20 DLY42 LI R1,10 12 DLY42A DEC R1 10 JNE DLY42A 10 RT 12 Unless I'm missing something, that should use 244 clock cycles. LI R1,5 would use 142 clock cycles; still more than enough delay. Opinions? (edit) I meant to say "if the 32K memory expansion is on the 16 bit bus" Edited December 28, 2018 by senior_falcon Quote Link to comment Share on other sites More sharing options...
Asmusr Posted December 27, 2018 Share Posted December 27, 2018 You can use CALL SAY("#TEXAS INSTRUMENTS"), something Mizapf once told me. 4 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted December 27, 2018 Share Posted December 27, 2018 I don't see any flaws in your reasoning about the timing. BTW, it's only the code to read the speech status that has to be in scratch pad, i.e. MOVB @SPCHRD,@SPSTATNOPNOPNOPRT The delay can run from 8-bit RAM. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 28, 2018 Share Posted December 28, 2018 Unless I'm missing something, that should use 244 clock cycles. LI R1,5 would use 142 clock cycles; still more than enough delay. Opinions? Not to put too fine a point on it, but it is 242 clock cycles. I agree with the 142. Since the delay times are minima, the minimum tolerance on the clock timer should be used. That is, at 3 MHz, nominally at 0.333 µs/cycle, the minimum tolerance is 0.3 µs. That said, I agree that the delay time is wrong. It is as though one of the instructions in the loop was considered only once and that the BL instruction was ignored. Considering the minimum 0.3 µs, a 42 µs delay would need 140 clock cycles to insure that delay, which your suggestion just covers on the 16-bit bus. ...lee Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 28, 2018 Author Share Posted December 28, 2018 You can use CALL SAY("#TEXAS INSTRUMENTS"), something Mizapf once told me. That's not in the XB manual. Are there any other undocumented tricks like that? I tried the ^ _ and > mentioned in the terminal emulator manual but they seem to have no effect in XB. Quote Link to comment Share on other sites More sharing options...
LASooner Posted December 28, 2018 Share Posted December 28, 2018 I read about it in this article.https://www.atarimagazines.com/compute/issue51/219_1_PROGRAMMING_THE_TI.php The XB manual mentions the speech editor command module manual, maybe it's in there. But I can't seem to find that one Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 28, 2018 Share Posted December 28, 2018 Pages 8 and 19 of the Speech Editor manual. Quote Link to comment Share on other sites More sharing options...
LASooner Posted December 28, 2018 Share Posted December 28, 2018 (edited) https://issuu.com/ataraxiom/docs/ti_speech_editorPage 8 EDIT: CS1 beat me by a minute Edited December 28, 2018 by LASooner 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 28, 2018 Share Posted December 28, 2018 EDIT: CS1 beat me by a minute Some people are years ahead of their time. I stay about 45 seconds ahead. 3 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 29, 2018 Author Share Posted December 29, 2018 Making good progress. Now I have a question about sending a string directly to the speech synthesizer. From the E/A manual, page 358: LI R2,SPEECH MOV *R2+,R3 LI R1,16 why 16? MOVB @H60,@SPCHWT BL @DLY12 LOOPR MOVB *R2+,@SPCHWT DEC R3 JEQ OUT DEC R1 JNE LOOPR LOOPB BL @READIT MOVB @SPDATA,R0 COC @H4000,R0 JNE LOOPB LI R1,8 why 8? JMP LOOPR To start with, 16 bytes are sent to the speech synthesizer. Then LOOPB waits till the speech is terminated. Then the rest of the string is sent 8 bytes at a time. Is there something special about these numbers? Can you send 8 bytes the first time instead of 16? Or what would be even more compact, could the string be sent 1 byte at a time like this? LI R2,SPEECH MOV *R2+,R3 MOVB @H60,@SPCHWT BL @DLY12 LOOPR MOVB *R2+,@SPCHWT DEC R3 JEQ OUT LOOPB BL @READIT MOVB @SPDATA,R0 COC @H4000,R0 JNE LOOPB JMP LOOPR 1 Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted December 29, 2018 Share Posted December 29, 2018 LOOPB waits until the SPEECH SYNTH'S internal buffer is half empty(8 Bytes)... IIRC. Ha! 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 29, 2018 Share Posted December 29, 2018 Making good progress. Now I have a question about sending a string directly to the speech synthesizer. From the E/A manual, page 358: <snip> To start with, 16 bytes are sent to the speech synthesizer. Then LOOPB waits till the speech is terminated. Then the rest of the string is sent 8 bytes at a time. Is there something special about these numbers? Can you send 8 bytes the first time instead of 16? Or what would be even more compact, could the string be sent 1 byte at a time like this? <snip> This from page 5 of the TMS 5220 Voice Synthesis Processor Data Manual: ...lee Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 29, 2018 Author Share Posted December 29, 2018 Thanks Lee! Look like I have to take a look at the manual, but I'm sure I'll have other questions. As a matter of fact, here is another: The big problem I have now is using direct speech. Word strings work fine: 10 CALL SAY("HELLO HOW ARE YOU") works as expected. 10 CALL SPGET("HELLO",A$) 20 CALL SAY(,A$) 30 GOTO 10 Gives chirping sounds in Classic99. Sometimes works in Win994a. This makes testing pretty much impossible. But the direct speech in Parsec works with both emulators. Maybe this has something to do with my equipment - I'm doing my TI work using XP running in a virtual box. Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted December 29, 2018 Share Posted December 29, 2018 Speech in Classic99 is mostly does-not-work. IIRC, @Tursi used the 5200 instead of the 5220 in his emulation. Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted December 29, 2018 Share Posted December 29, 2018 I developed most of my speech solutions using MESS 0.79. No issues. 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 29, 2018 Author Share Posted December 29, 2018 My interest in implementing direct speech is pretty small, so I'm not about to dive into MESS just so I can test it out. Let me run a few questions past the folks who know about these things. Let's set the stage: When you CALL SPGET("any word",A$), the first two bytes of A$ always seem to be >60 and >00. So by writing 17 bytes you first write >60 to tell the synthesizer you will be loading speech data directly, then another 16 bytes and then 8 at a time as necessary. 1 - should I load the 0 that follows the >60, or should that be bypassed? 2 - is there some byte or combination of bytes to tell the synthesizer it is finished with the word, or does it know that when the buffer is empty? 3 - If there are additional strings that are direct speech I would need to be sure the buffer is empty before sending them to SPCHWT. How is that done? 4 - After the buffer is empty can I send another string for direct speech just like the first one by writing >60 and then the string or is some setup necessary? 5 - If mixing direct speech and looked up speech (i.e. something like CALL SAY("HELLO",A$,"HOW",,"ARE",B$,,C$)) does anything need to be done to keep the new word from starting before the previous one is done? Thanks! Below is the code for direct speech, adapted from the E/A manual. *feeds a string directly to synth per page 358 EA manual *R0 points to 1st character in string; R2 has length DIRECT LI R1,17 the >60 and then 16 bytes to buffer DRCTL2 MOVB *R0+,@SPCHWT first byte in string from SPGETis always >60 DEC R2 done feeding string to synth JEQ SYNTH go back and see if there is another string to speak DEC R1 JNE DRCTL2 DRCTL3 BL @>8330 COC @H4000,R12 JNE DRCTL3 LI R1,8 JMP DRCTL2 Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 30, 2018 Share Posted December 30, 2018 Speech in Classic99 is mostly does-not-work. IIRC, @Tursi used the 5200 instead of the 5220 in his emulation. Other way around, but the bigger issue is the timing is whacked and the CPU halt function doesn't work. It tends to mostly-work in well-behaved software that feeds data when the FIFO is low, or uses the built-in words, but I wouldn't rely on it. (In fairness, there WAS no 5200 emulation available when I plugged it in, MESS was using the 5220 too. ). 3 Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted December 30, 2018 Share Posted December 30, 2018 (edited) 1 - should I load the 0 that follows the >60, or should that be bypassed? >60(byte) should be followed by one word indicating the number of bytes of LPC you will be sending(length)... >XXXX(word). Let's set the stage: When you CALL SPGET("any word",A$), the first two bytes of A$ always seem to be >60 and >00. The >00 here is the "high byte" of the the number of bytes of LPC you will be sending(length). This was done because the longest string you can send (A$) is 255 bytes >00FF(word). Thus the byte that follows the >60 >00 is the "low byte" of the number of bytes of LPC you will be sending(length). Letting the buffer empty completely before sending the length of bytes you had previously specified, will likely crash the speech processor. 2 - is there some byte or combination of bytes to tell the synthesizer it is finished with the word, or does it know that when the buffer is empty? 3 - If there are additional strings that are direct speech I would need to be sure the buffer is empty before sending them to SPCHWT. How is that done? 4 - After the buffer is empty can I send another string for direct speech just like the first one by writing >60 and then the string or is some setup necessary? After you have finished sending the length of bytes you had previously specified be sure(IIRC) to wait for the buffer to empty completely. before sending the next >60. Lee's info(above) should help in a crunch! Edited December 30, 2018 by HOME AUTOMATION Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 30, 2018 Author Share Posted December 30, 2018 That is very helpful information! The third bit of the status register (BE) is high when the buffer is empty. So to check that the buffer is empty, with the buffer copied to R12 I just have to COC @H2000,R12 and when it is EQ then the buffer is empty. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 30, 2018 Author Share Posted December 30, 2018 So now my latest problem with implementing speech is making SPGET work. According to the XB manual, The value of word-string is any string value listed in Appendix L. In other words, the word has to be found in the speech synth's vocabulary for SPGET to return anything useful. That seems to be true; words such as TEYLA and MAKIT are not in the resident vocabulary and both return the same string, which says "Uh-oh". For the word "HELLO", the lookup routine that I cribbed from the EA manual finds an address of >351A which agrees with the address given in appendix 24.6 of the EA manual. But when I extract the string at that address from the speech synth, it is nothing like the string I get with CALL SPGET("HELLO",A$). Should they be the same? I assume this is a level 8 error, but I'm darned if I can see where it is. I can post code if that would help. Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted December 30, 2018 Share Posted December 30, 2018 But when I extract the string at that address from the speech synth, it is nothing like the string I get with CALL SPGET("HELLO",A$). Should they be the same?. How are you extracting? I'm sure I forget. The BBC MICRO uses the same speech synth. IIRC, because the interface uses BIG vs. LITTLE ENDIAN the bytes need to be reversed...rather than install a dedicated routine to accomplish this, the bytes have been pre-reversed in rom... just a thought. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 31, 2018 Author Share Posted December 31, 2018 This was all done with Classic99. I set up a little routine running from MiniMemory that copies the rom in the speech synthesizer into expansion memory. >0000 in the synthesizer is copied to >A000 in expansion ram. Then you can use the debugger to explore the speech synth's rom. At >0000 is >AA . That is used to determine if the speech synth is attached. Then you can see a table of words that can be spoken. I looked for "ABOUT" and found it at >A09B which is >009B in the synthesizer. At >009B I found this: 5 ABOUT 0 0 0 0 0 17 14 55 That all makes sense: length byte and the string, then some zeros (why?) then >1714 and >55 . >1714 is the address of the code in the synth rom which agrees with the EA manual and the >55 is the length byte When you CALL SPGET("ABOUT",A$) and then look at the bytes that make up the string you see (dec) 96 0 85 161 8 46 207 74 219 247 98 84 ......... The length byte is 85 which is the same as >55 above. But when you look at the data at >1714 it is (hex) 85 10 74 F3 52 DB EF 46 ........ I just checked on the real TI and the string returned for ABOUT is the same as you get in Classic99. After re-reading your post I took the first 4 decimal numbers, 161,8,46,207, reversed the bits and converted to hex to get >85,10,74,F3. So that's the answer and once again I thank you! 3 Quote Link to comment Share on other sites More sharing options...
HOME AUTOMATION Posted December 31, 2018 Share Posted December 31, 2018 Looks like I had a good, couple of days...Glad, anytime I can assist in a good cause...Keep up the good work! Ah!Ha! 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 31, 2018 Author Share Posted December 31, 2018 SPGET is now working properly when compiled. A couple of days to test and this will be ready to go. 4 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted January 1, 2019 Author Share Posted January 1, 2019 All set to release this but just discovered that the changes to the compiler make it with certain sequences of instructions. I'm probably mesing up a register that should be left alone. Tonight's new years eve, so I will turn off the computer and have a few drinks to celebrate. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.