Jump to content
IGNORED

XB Game Developers Package


senior_falcon

Recommended Posts

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 by senior_falcon
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
  • Like 1
Link to comment
Share on other sites

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:

 

post-29677-0-97875700-1546048444.png

 

...lee

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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. ;) ).

  • Like 3
Link to comment
Share on other sites

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 by HOME AUTOMATION
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!

  • Like 3
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...