Prev: 01CD Up: Map Next: 02AD
021F: Parse Speech String
Used by the routine at HandleInterrupt.
Expand the contents of s$ into the allophone buffer. A leading "*" or "?" means the string has already been spoken.
Input
HL Pointer to s$
Read the length of s$ and ignore an empty string.
ParseSpeechString 021F INC HL Fetch the low length byte of s$.
0220 LD E,(HL)
0221 XOR A Test whether the low length byte is zero.
0222 CP (HL)
0223 INC HL Fetch the high length byte of s$.
0224 LD D,(HL)
0225 JR NZ,ParseSpeechString_Body Jump to ParseSpeechString_Body if the low length byte is non-zero.
0227 CP (HL) Return if s$ is empty.
0228 RET Z
Leave strings that have already been spoken.
ParseSpeechString_Body 0229 INC HL Move to the first character.
022A LD A,$2A Return if s$ starts with "*".
022C CP (HL)
022D RET Z
022E LD A,$3F Return if s$ starts with "?".
0230 CP (HL)
0231 RET Z
0232 DEC HL Move back to the length.
0233 PUSH HL Stash the start of s$ on the stack.
0234 ADD HL,DE Point DE at the end of s$.
0235 EX DE,HL
0236 POP HL Restore the start of s$ from the stack.
0237 CALL ReadBufferPointer Call ReadBufferPointer.
Convert the next character of s$ into allophones.
ParseSpeechString_Next 023A PUSH BC Stash the buffer pointer on the stack.
023B INC HL Fetch the next character from s$.
023C LD A,(HL)
023D CALL NormaliseCharacter Call NormaliseCharacter.
0240 CP $0E Jump to ParseSpeechString_TestGroup if this is not a full stop.
0242 JR NZ,ParseSpeechString_TestGroup
0244 LD A,$04 Load A with PA5 (the longest pause) for a full stop.
0246 POP BC Restore the buffer pointer from the stack.
0247 LD (BC),A Queue the first PA5.
0248 DEC BC
0249 CALL CheckBufferSpace Call CheckBufferSpace and return if the buffer is full.
024C RET C
024D PUSH BC Stash the buffer pointer on the stack.
024E JR ParseSpeechString_Store Jump to ParseSpeechString_Store to queue a second PA5, with the intonation bit.
A "(" starts a parenthesised allophone name.
ParseSpeechString_TestGroup 0250 CP $08 Jump to ParseSpeechString_Map if this is not "(".
0252 JR NZ,ParseSpeechString_Map
0254 CALL ParseAllophoneGroup Call ParseAllophoneGroup and jump to ParseSpeechString_Store if the name was valid.
0257 JR NC,ParseSpeechString_Store
0259 POP BC Restore the buffer pointer from the stack.
025A JR ParseSpeechString_Mark Jump to ParseSpeechString_Mark.
Map the character through CharacterKeys.
ParseSpeechString_Map 025C PUSH HL Stash the string pointer on the stack.
025D LD HL,$03AF Search CharacterKeys and jump to ParseSpeechString_Mapped if this letter is known.
0260 LD BC,$001B
0263 CPIR
0265 JR Z,ParseSpeechString_Mapped
0267 POP HL Restore the string pointer and the buffer pointer from the stack.
0268 POP BC
This character is not valid. Put a "?" on the character after it (or on the last character), and then on the first character.
ParseSpeechString_Mark 0269 INC DE Point DE one past the end of s$ and HL at the next character.
026A INC HL
ParseSpeechString_Bound 026B PUSH HL Jump to ParseSpeechString_Query if HL is still inside s$.
026C OR A
026D SBC HL,DE
026F POP HL
0270 JR C,ParseSpeechString_Query
0272 DEC HL Otherwise move back to the last character.
0273 JR ParseSpeechString_Bound Jump to ParseSpeechString_Bound.
The "?" path and the buffer-full returns never reach WriteBufferPointer, so allophones already queued for this string are discarded. On buffer-full, s$ is left unmarked and is retried on every interrupt. An s$ too long for the buffer never speaks.
ParseSpeechString_Query 0275 LD C,$3F Write "?" there and jump to ParseSpeechString_Term to write another over the first character.
0277 LD (HL),C
0278 JR ParseSpeechString_Term
ParseSpeechString_Mapped 027A LD BC,$0035 Fetch the allophone at the same index in AllophoneValues.
027D ADD HL,BC
027E LD A,(HL)
027F POP HL Restore the string pointer from the stack.
Apply intonation and queue the allophone.
ParseSpeechString_Store 0280 LD B,A Keep the allophone in B.
0281 XOR A Set the flags-byte index.
0282 PUSH HL Stash the string pointer on the stack.
0283 CALL ReadWorkspace Call ReadWorkspace for the flags byte.
0286 POP HL Restore the string pointer from the stack.
0287 AND %01000000 Keep only bit 6 (intonation).
0289 ADD A,B Apply the intonation bit to the allophone.
028A POP BC Restore the buffer pointer from the stack.
028B LD (BC),A Queue the allophone in the speech buffer.
028C DEC BC
028D CALL CheckBufferSpace Call CheckBufferSpace and return if the buffer is full.
0290 RET C
0291 PUSH HL Jump to ParseSpeechString_Next if there are still characters left in s$.
0292 SBC HL,DE
0294 POP HL
0295 JR C,ParseSpeechString_Next
0297 XOR A Write PA1 (00) to the speech buffer to end the phrase.
0298 LD (BC),A
0299 DEC BC
029A CALL CheckBufferSpace Call CheckBufferSpace and return if the buffer is full.
029D RET C
029E CALL WriteBufferPointer Call WriteBufferPointer.
02A1 LD C,$2A Use "*" as the "already spoken" marker.
Overwrite the first character of s$ so it will not be spoken again.
ParseSpeechString_Term 02A3 LD A,$53 Call FindVariable for "s$".
02A5 CALL FindVariable
02A8 INC HL Move to the first character of s$.
02A9 INC HL
02AA INC HL
02AB LD (HL),C Mark s$ as already spoken.
02AC RET Return.
Prev: 01CD Up: Map Next: 02AD