Jump to content
Sign in to follow this  

Decoupling the speech in TEII from the cart into XB

Recommended Posts

Don't know if anyone has thought of this yet, or if it's been done - 


Is it possible to decouple the speech routines and allophones in ROM from the TEII cart and build it into an XB cart (RXB, TIXB, etc.)?


I've always wanted to use the speech routines in XB instead of BASIC/TEII, and not to have to load them from PHD5076.  There's also supposedly a Republic Software package that had speech in it (Utilities 1? - I don't really remember) that could be loaded. (Another squirrel - does anyone have this disk image?)


On a side note, is PHD5076 the exact same thing as TEII routines?  Or are they different?  


  • Like 2

Share this post

Link to post
Share on other sites

I'm pretty sure the PHD5076 routines are the same ones used with the TE-II module. They were also used in the Berlin PEB Speech adapter from Winfried Winkler and in the later SNUG Speech card.


I may have a copy of Utilities I. If I do, I'll check the manual to validate the contents.

  • Like 2

Share this post

Link to post
Share on other sites

There was a stand-alone program that could do it from CALL LINKs if I remember correctly. Somebody took the TEII code and wrapped it up as an assembly utility. This was 30 od years ago. It's around somewhere.

  • Like 2

Share this post

Link to post
Share on other sites

I'd looked into this some years back, but, decided not to pursue, due to lack of both hardware resources, and knowledge. I instead opted to find a way to capture the LPC for single words/short phrases.


Along the way I did uncover some details. I think your Idea should be more doable using some of today's resources, such as the FinalGROM 99, page switching, Classic99's, debugger/speech capabilities.


Some background... Regarding TE-II, Text to Speech...


The speech routine equivalents of XLAT, SPEAK, are located in the 4K-ROM, mapped to >6000->7FFF.


XLAT, enters at >6562cpu, and processes words/phases located at >xxxxvdp, and places the resultant allophone string at >35DEvdp, ...xxxx, seems to vary somewhat.


SPEAK, enters at >6016cpu.


There is a third XML vector in the 4K ROM(>6CAA), but, it's not ALPHON.


ALPHON seems to be written in GPL.


It appears that the DATABASE is stored in GROM(s) 5/6.


EXTENDED BASIC, also uses GROMs 3, thru 6. That only leaves 1, GROM, free. See the problem?:(


Also TE-II's STRREF, and STRASG, target areas in VDP, that seem to be used differently by XB.


The "Text to Speech - English[PHD 5076]" disk's routines were written to take advantage of their "running from RAM".


The routines on this disk are RELOCATABLE. I'm fairly certain that I could trick the LOADER into loading these to various extra RAM, pages at >7000, in a FinalGROM 99. That would free-up some space in the lower 8K. However, these routines enjoy using the UTILS, in LOWRAM, and would still need their names present in the DEF table. You would also need three words per routine, in order to switch pages and branch to them. Plus, you would need three words to switch the page back and return to the BASIC interpreter, which can be shared between routines.


That said, the DATABASE is 16K, and takes up >A000, thru >CFFF, in HIGHMEM. Do they even mention that in the manual!?


All this would only save slightly more than 4K of LOWRAM. To save more, the DATABASE would have to be relocated as well ...now our work-load goes up a bit more.:twisted:

  • Like 4

Share this post

Link to post
Share on other sites
On 2/10/2022 at 7:59 AM, HOME AUTOMATION said:

That said, the DATABASE is 16K, and takes up >A000, thru >CFFF, in HIGHMEM. Do they even mention that in the manual!?

**That said, the DATABASE is 12K, and takes up >A000, thru >CFFF, in HIGHMEM. Do they even mention that in the manual!?**




Here however, I was most certainly correct! This can easily be back-checked by using the proper rule of synergistics:

The sum of the parts is always greater than the whole.
Perhaps my way of evaluating the premise is a Bit more advanced!:grin:


On 2/10/2022 at 7:59 AM, HOME AUTOMATION said:

I'm fairly certain that I could trick the LOADER into loading these to various extra RAM, pages at >7000, in a FinalGROM 99.


I meant to add here, that: By using the FG99's, advanced SAVE feature, the loaded routines will be incorporated into XB's, .bin file. Perhaps somewhat fulfilling the original goal... "I've always wanted to use the speech routines in XB instead of BASIC/TEII, and not to have to load them from PHD5076.:ponder:

Share this post

Link to post
Share on other sites

This is the entire SPEECH routines in XB in GPL:

[2924]               ***********************************************************
[2925]               * CALL SAY(....................)                          *
[2926]               *  Decode given parameter(s). Store all data first, then  *
[2927]               *   go speak it all at once.                              *
[2928]               ***********************************************************
[2929] B13B 06,A9,81 SAY    CALL COMB              Must start with "("
[2930] B13E BD,4C,6E        DST  @VSPTR,@FAC2      Save current top of stack on
[2931] B141 0F,77           XML  VPUSH              the stack
[2932] B143 BF,0C,00        DST  255,@BYTES        255 bytes = 85 3 byte entires
       B146 FF
[2933] B147 0F,71           XML  GETSTR            Get temp speech list string
[2934] B149 BF,4A,00        DST  >001C,@FAC        Indicate it is temp string (S

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0051 
       B14C 1C
[2935] B14D BF,4C,65        DST  >6500,@FAC2       Indicate it is string entry
       B150 00
[2936] B151 BD,4E,1C        DST  @SREF,@FAC4       Save pointer to temp string
[2937] B154 BD,50,0C        DST  @BYTES,@FAC6      Length is 255
[2938] B157 0F,77           XML  VPUSH             Make it semi-permenant
[2939]               * Set up pointers into the speak list
[2940] B159 BD,00,4E        DST  @FAC4,@PTFBSL     Front points to begining
[2941] B15C BD,02,4E        DST  @FAC4,@PTLBSL     Last now points to beginning
[2942] B15F BD,04,00        DST  @PTFBSL,@PTEBSL
[2943] B162 A1,04,50        DADD @FAC6,@PTEBSL     End points to the end+1
[2944] B165 06,B5,81        CALL SETRW             Set PHROM read/write address
[2945] B168 06,B5,76        CALL WAIT              Wait till no one is speaking
[2946] B16B 06,B3,4E DIRSPK CALL GETPRM            Get next parameter
[2947] B16E 71,E2           BS   NEXT1             If non-null ASCII string
[2948] B170 BD,06,4E        DST  @FAC4,@PTFCIS     Set up pointer to first char
[2949] B173 BD,0A,50        DST  @FAC6,@PTLCIS     Set ptr-to-last-char-in-strin
[2950] B176 A1,0A,06        DADD @PTFCIS,@PTLCIS    by adding length-of-string
[2951] B179 93,0A           DDEC @PTLCIS            and subtracting 1
[2952]               * Make a speech list
[2953] B17B 06,B5,81        CALL SETRW             Set speech read/write addrs
[2954] B17E BD,08,06        DST  @PTFCIS,@PTCCIS   Start at beginning of string
[2955] B181 86,4C           CLR  @TOTTIM           Clear total time delay
[2956] B183 06,B3,CB        CALL GETTIM            Get first timing mark
[2957] B186 06,B3,BB        CALL TIMING            Get any subsequent marks
[2958]               * The total first time delay is in TOTTIM now
[2959] B189 C5,08,0A GB158  DCH  @PTLCIS,@PTCCIS   While more string
[2960] B18C 71,D8           BS   GB1A7
[2961] B18E 06,B3,64        CALL PHRASE            Get next phrase
[2962]               * If spell flag is 0, try to look the phrase up. If it
[2963]               * can not be found, then set the spell flag, and it will be
[2964]               * spelled out. If found, save on speak list.
[2965] B191 8E,4B           CZ   @SPLFLG           There is a phrase
[2966] B193 51,A4           BR   GB173
[2967] B195 06,B4,60        CALL LOOKUP            Try to look it up in the PHRO
[2968] B198 8F,4D           DCZ  @DATAAD           If not found then
[2969] B19A 51,A1           BR   GB170
[2970] B19C BE,4B,01        ST   1,@SPLFLG         Set the spell flag
[2971] B19F 51,A4           BR   GB173
[2972] B1A1 06,B5,66 GB170  CALL STDATA            Store data in list
[2973]               * If spell flag is 1, set time delay to >3C, and take the
[2974]               * phrase one character at a time (spell it). Look up each
[2975]               * character: if not found, use 'UHOH' data instead.
[2976]               * Regardless, store data on speak list.
[2977] B1A4 D6,4B,01 GB173  CEQ  1,@SPLFLG         Need to spell it out?
[2978] B1A7 51,D1           BR   GB1A0
[2979] B1A9 BD,4F,10        DST  @PTLCIP,@PTLCIL   Est last char to spell out
[2980] B1AC BE,4C,3C        ST   >3C,@TOTTIM       >3C used because sounds good
[2981]               *                      Take each single character
[2982]               * Skip over any embedded spaces encountered in a phrase
       B1B2 20
[2984] B1B3 51,B9           BR   GB188
[2985] B1B5 91,0C           DINC @PTFCIP
[2986] B1B7 51,AF           BR   GB17E
[2987]               * Set first and last pointers to same one character
[2988] B1B9 BD,10,0C GB188  DST  @PTFCIP,@PTLCIP
[2989] B1BC 06,B4,60        CALL LOOKUP            Try to look it up
[2990]               * If not found, use data to 'UHOH'
[2991] B1BF 8F,4D           DCZ  @DATAAD
[2992] B1C1 51,C7           BR   GB196
[2993] B1C3 BF,4D,71        DST  >71F4,@DATAAD     Put addr of 'UHOH' in
       B1C6 F4
[2994] B1C7 06,B5,66 GB196  CALL STDATA            Store data on speak list

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0052 
[2995] B1CA 91,0C           DINC @PTFCIP           Go on to next character
[2996] B1CC C5,0C,4F        DCH  @PTLCIL,@PTFCIP   Until done all
[2997] B1CF 51,AF           BR   GB17E
[2998]               * At this point, get next timing group. The first timing
[2999]               * character has already been found, and it's value is still
[3000]               * in TIMLEN. Therefore, initiatory call to GETTIM not
[3001]               * needed. Simply clear TOTTIM and call TIMING.
[3002] B1D1 86,4C    GB1A0  CLR  @TOTTIM
[3003] B1D3 06,B3,BB        CALL TIMING
[3004] B1D6 51,89           BR   GB158
[3005]               * At this point, finished all the phrases in this string.
[3006]               * TOTTIM should equal >FE, it indicate end of sting If it
[3007]               * doesn't equal >FE, it indicates that a timing group was
[3008]               * put on the end of the string. Therefore, save the timing
[3009]               * group with a null data address to show it is only timing.
[3010] B1D8 D6,4C,FE GB1A7  CEQ  >FE,@TOTTIM
[3011] B1DB 71,E2           BS   NEXT1
[3012] B1DD 87,4D           DCLR @DATAAD
[3013] B1DF 06,B5,66        CALL STDATA
[3014]               * Next item could be direct string.
[3015] B1E2 D6,42,B3 NEXT1  CEQ  COMMAZ,@CHAT      If direct string present
[3016] B1E5 51,FC           BR   SPEAK
[3017] B1E7 06,B3,4E        CALL GETPRM            Get the next parameter
[3018] B1EA 71,F7           BS   NEXT2             If non-null direct string
[3019] B1EC BE,4C,FF        ST   >FF,@TOTTIM       Mark TOTTIM as direct string
[3020] B1EF 0F,77           XML  VPUSH             Save direct string on stack
[3021] B1F1 BD,4D,6E        DST  @VSPTR,@DATAAD    Store stack addr on string
[3022] B1F4 06,B5,66        CALL STDATA            And add to the speak list
[3023]               * If the next character is a comma, loop thru it again
[3024] B1F7 D6,42,B3 NEXT2  CEQ  COMMAZ,@CHAT
[3025] B1FA 71,6B           BS   DIRSPK
[3026]               * If end fall into SPEAK
[3027]               ***********************************************************
[3028]               * SPEAK will actually speak the speech list. It tests the
[3029]               * timing byte to see if it is an >FF. If it is, then the
[3030]               * data following it points to a direct speech data string
[3031]               * in VDP. If it is not, then the data following it points
[3032]               * to a PHROM speech data list. In the first case, this
[3033]               * routine will issue a speak external command to the PHROM
[3034]               * and then feed bytes out to the PHROM as it requests them.
[3035]               * In the second case, the address will be loaded out to the
[3036]               * PHROM, and then a speak command will be issued.
[3037]               ***********************************************************
[3038] B1FC 06,B5,81 SPEAK  CALL SETRW             Set read/write address
[3039] B1FF C9,00,02 GB1CE  DCHE @PTLBSL,@PTFBSL   More speech list to go
[3040] B202 72,89           BS   GB258
[3041] B204 06,B5,76        CALL WAIT              Yes, wait until previous
[3042]               *                              speech is though
[3043] B207 D6,B0,00        CEQ  >FF,V*PTFBSL      External speech data
       B20A FF
[3044] B20B 72,2F           BS   GB1FE
[3045] B20D BC,79,B0        ST   V*PTFBSL,@TIMER   No, load timer
       B210 00
[3046] B211 82,79           NEG  @TIMER             and neg it to correct
[3047] B213 BD,12,E0        DST  [email protected](@PTFBSL),@PTFBPH   Put addr into PTFBPH
       B216 01,00
[3048] B218 A3,00,00        DADD 3,@PTFBSL               and skip to next node
       B21B 03
[3049] B21C D2,79,00 LOOP1  CGE  0,@TIMER          Wait for time delay
[3050] B21F 52,1C           BR   LOOP1
[3051] B221 8E,12           CZ   @PTFBPH           If there is data
[3052] B223 72,2D           BS   GB1FC
[3053] B225 06,B5,1C        CALL LOADAD            Load the addr to PHROM
[3054] B228 BE,C0,00        ST   >50,@PAD(@WRITE)   and issue speak command

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0053 
       B22B 5A,50
[3055] B22D 52,86    GB1FC  BR   CONTIN
[3056] B22F 91,00    GB1FE  DINC @PTFBSL           Speak external, skip over >FF
[3057] B231 BD,5E,B0        DST  V*PTFBSL,@PTCBED  Set up pointer to 1st byte
       B234 00
[3058] B235 BD,5E,E0        DST  [email protected](@PTCBED),@PTCBED    in external speech data
       B238 04,5E
[3059] B23A 95,00           DINCT @PTFBSL          Skip addr bytes
[3060] B23C BC,62,EF        ST   [email protected](@PTCBED),@LENWST  Get Len of whole string
       B23F FF,FF,5E
[3061] B242 A6,62,03 DIRSPH SUB  3,@LENWST         Minus 3 bytes overhead
[3062]               * All external speech strings start with a >60
[3063] B245 D6,B0,5E        CEQ  >60,V*PTCBED      Bad speech string
       B248 60
[3064] B249 4D,4D           BR   ERRBV
[3065] B24B 06,B5,76        CALL WAIT              Wait for go ahead
[3066] B24E 95,5E           DINCT @PTCBED          Skip spk ext & 1st byte len
[3067] B250 BC,60,B0        ST   V*PTCBED,@LENCST  Get len of current string
       B253 5E
[3068] B254 91,5E           DINC @PTCBED           Skip len byte to 1st real byt
[3069] B256 BE,56,10        ST   16,@TEMP2         Do 1st 16 bytes (fill buff)
[3070] B259 BE,C0,00        ST   >60,@PAD(@WRITE)  Start Speak External
       B25C 5A,60
[3071] B25E BC,C0,00 LOOPR  ST   V*PTCBED,@PAD(@WRITE) Write byte to PHROM
       B261 5A,B0,5E
[3072] B264 91,5E           DINC @PTCBED           Go to next byte
[3073] B266 92,62           DEC  @LENWST           1 less char in whole string
[3074] B268 72,86           BS   CONTIN            Finished whole string?
[3075] B26A 92,60           DEC  @LENCST           1 less char in curr string
[3076] B26C 72,42           BS   DIRSPH            Finished current string?
[3077] B26E 92,56           DEC  @TEMP2            1 less char in this loop
[3078] B270 52,5E           BR   LOOPR             Not finished curr loop yet?
[3079] B272 BC,69,C0 GB241  ST   @PAD(@READ),@SPKSTS Read status from PHROM
       B275 00,58
[3081]               * If the next statement is true, it means that speak was
[3082]               * probably interupted and that it is shot at this point.
[3083]               * Therefore, we are going to quit now.
[3084] B277 DA,69,80        CLOG >80,@SPKSTS
[3085] B27A 72,86           BS   CONTIN
[3086] B27C DA,69,40        CLOG >40,@SPKSTS       Loop till buff below half
[3087] B27F 72,72           BS   GB241
[3088] B281 BE,56,08        ST   8,@TEMP2          Put 8 more bytes to PHROM
[3089] B284 52,5E           BR   LOOPR              and go do these
[3090] B286 05,B1,FF CONTIN B    GB1CE             We've said it all!!
[3091]               * Now pop all entries off stack that we put on!
[3092] B289 0F,78    GB258  XML  VPOP              Free up a temporary string
[3093] B28B D5,6E,4C        DCEQ @FAC2,@VSPTR
[3094] B28E 52,89           BR   GB258
[3095] B290 4A,96           BR   LNKRTN       
[3096]               ***********************************************************
[3097]               * SPGET subprogram. Load speech data from external device.
[3098]               *       Use standard file I/O
[3099]               ***********************************************************
[3100]               * CALL SAY(word-string,return-string)                     *
[3101]               ***********************************************************
[3102] B292 06,A9,81 SPGET  CALL COMB             Must have left parenthesis
[3103] B295 06,B5,81        CALL SETRW             Set PHROM read/write address
[3104] B298 06,B5,76        CALL WAIT              Wait till no one is speaking
[3105] B29B 06,B3,4E NXTPAR CALL GETPRM            Get the next parameter
[3106] B29E 8F,50           DCZ  @FAC6             If non-null ASCII string
[3107] B2A0 73,47           BS   GB318
[3108] B2A2 BD,06,4E        DST  @FAC4,@PTFCIS     Pointer to 1st char in string
[3109] B2A5 BD,0A,50        DST  @FAC6,@PTLCIS     Pointer to last-char-in-strin

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0054 
[3110] B2A8 A1,0A,06        DADD @PTFCIS,@PTLCIS    by adding length-of-string
[3111] B2AB 93,0A           DDEC @PTLCIS             and subtracting 1
[3112] B2AD 06,B5,81        CALL SETRW             Set the speech read/write add
[3113] B2B0 BD,08,06        DST  @PTFCIS,@PTCCIS   Set curr char to first char
[3114] B2B3 86,4C           CLR  @TOTTIM           Clear total time delay
[3115] B2B5 06,B3,CB        CALL GETTIM            Get first timing mark
[3116] B2B8 06,B3,BB        CALL TIMING            Get any subsquent marks
[3117]               * Get one phrase, and look it up. If the phrase is not foun
[3118]               * substitute in 'UHOH'.
[3119] B2BB C5,08,0A        DCH  @PTLCIS,@PTCCIS   Possible phrase
[3120] B2BE 73,47           BS   GB318
[3121] B2C0 06,B3,64        CALL PHRASE            Yes, go get it
[3122] B2C3 D6,4B,01        CEQ  1,@SPLFLG         Spell flag set then set
[3123] B2C6 52,CB           BR   GB29C
[3124] B2C8 BD,10,0C        DST  @PTFCIP,@PTLCIP    last ptr to first (1 char)
[3125] B2CB 06,B4,60 GB29C  CALL LOOKUP            Look up the phrase
[3126] B2CE 8F,4D           DCZ  @DATAAD           If not there,
[3127] B2D0 52,D9           BR   GB2AA
[3128] B2D2 BF,4D,71        DST  >71F4,@DATAAD      use 'UHOH' data addr
       B2D5 F4
[3129] B2D6 BE,64,51        ST   >51,@STRLEN        'UHOH' data length
[3130]               * Data must be in PHRADD and PHLEN, so move it
[3131] B2D9 BD,01,4D GB2AA  DST  @DATAAD,@PHRADD
[3132] B2DC BC,00,64        ST   @STRLEN,@PHLEN
[3133] B2DF A2,00,03        ADD  3,@PHLEN          For overhead info
[3134]               * There must be a variable to put this data in. If not, err
[3135] B2E2 0F,7E           XML  SPEED
[3136] B2E4 00              BYTE SYNCHK
[3137] B2E5 B3              BYTE COMMAZ
[3138] B2E6 0F,7A           XML  SYM               Find symbol in table
[3139] B2E8 0F,7B           XML  SMB               Evaluate andy subscripts
[3140] B2EA 0F,77           XML  VPUSH             Save for assignment
[3141] B2EC 86,0C           CLR  @BYTES            Two byte value
[3142] B2EE BC,0D,00        ST   @PHLEN,@BYTES+1   Length of string needed
[3143] B2F1 0F,71           XML  GETSTR            Get a string for the data
[3144] B2F3 06,B5,81        CALL SETRW             Set up speech read/write addr
[3145] B2F6 BF,4A,00        DST  >001C,@FAC        Now build string FAC entry
       B2F9 1C
[3146] B2FA BF,4C,65        DST  >6500,@FAC2       String ID
       B2FD 00
[3147] B2FE BD,4E,1C        DST  @SREF,@FAC4       Pointer to string
[3148] B301 BD,50,0C        DST  @BYTES,@FAC6      Length of string
[3149] B304 BF,B0,1C        DST  >6000,V*SREF      Mark string as speech data
       B307 60,00
[3150] B309 BC,E0,02        ST   @PHLEN,[email protected](@SREF) Put in string length
       B30C 1C,00
[3151] B30E A7,E0,01        DSUB 3,[email protected](@SREF)       minus thei info
       B311 1C,00,03
[3152]               * LOADAD expects addr to be in PTFBPH, so move it.
[3153] B314 BD,12,01        DST  @PHRADD,@PTFBPH
[3154] B317 06,B5,1C        CALL LOADAD
[3155]               * Going to copy string from PHROM to VDP. The actual data
[3156]               * from PHROM is in bit-reversed order, so must reverse the
[3157]               * order after reading in the order. Remember that 3 bytes
[3158]               * PHLEN are our own overhead, so don't copy all
[3159] B31A C6,00,03 GB2EB  CH   3,@PHLEN
[3160] B31D 53,45           BR   GB316
[3161] B31F BE,C0,00        ST   >10,@PAD(@WRITE)   Issue read byte command
       B322 5A,10
[3162] B324 BC,68,C0        ST   @PAD(@READ),@BYTE3 Read the byte
       B327 00,58
[3163]               * the following code is somewhat tricky. It will bit
[3164]               * reverse the contents of BYTE3 into BYTE1 through
[3165]               * BYTE2 by means of word shifts. Note the definition of

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0055 
[3166]               * BYTE1 , BYTE2, and BYTE3 in EQU's. You might try an
[3167]               * example if it isn't clear what is going on.
[3168] B329 86,67           CLR  @BYTE2
[3169] B32B BE,54,08        ST   >08,@TEMP1
[3170] B32E EB,67,00 RNDAG  DSRC 1,@BYTE2
       B331 01
[3171] B332 E3,66,00        DSLL 1,@BYTE1
       B335 01
[3172] B336 92,54           DEC  @TEMP1
[3173] B338 53,2E           BR   RNDAG
[3174]               * Store the bit-corrected byte into the string & inc str pt
[3175] B33A BC,E0,03        ST   @BYTE1,[email protected](@SREF)
       B33D 1C,66
[3176] B33F 91,1C           DINC @SREF
[3177] B341 92,00           DEC  @PHLEN            Dec the string length
[3178] B343 53,1A           BR   GB2EB             Go do next char if there is o
[3179] B345 0F,7C    GB316  XML  ASSGNV            Assign the string to variable
[3180] B347 D6,42,B3 GB318  CEQ  COMMAZ,@CHAT      If more go do
[3181] B34A 72,9B           BS   NXTPAR
[3182] B34C 4A,96           BR   LNKRTN
[3183]               ***********************************************************
[3184]               * GETPAM gets the next string paameter passed to the
[3185]               * routine. If that parameter is non-exist or null, then
[3186]               * condition bit is set. If the parameter is there then
[3187]               * condition bit is reset and the FAC entry describes the
[3188]               * string. In either case, return with condition is done.
[3189]               ***********************************************************
[3190] B34E 0F,79    GETPRM XML  PGMCHR            Get next token
[3191] B350 D6,42,B3        CEQ  COMMAZ,@CHAT      Go set condition no parm
[3192] B353 73,60           BS   SETCB
[3193] B355 0F,74           XML  PARSE
[3194] B357 B6              BYTE RPARZ
[3195] B358 D6,4C,65        CEQ  >65,@FAC2         If not string, error
[3196] B35B 4D,1D           BR   ERRSNM
[3197] B35D 8F,50           DCZ  @FAC6             Set cond if null string
[3198] B35F 01              RTNC                   Else return
[3199] B360 D4,00,00 SETCB  CEQ  @PAD,@PAD         Set condition bit
[3200] B363 01              RTNC
[3201]               ***********************************************************
[3202]               * Get the next phrase out of the current string. The phrase
[3203]               * may begin with a #, which means it will continue to the
[3204]               * next #, or it many begin with an ordinary character, in
[3205]               * which case it will end with the character just before the
[3206]               * first timing character encountered. In either case, the
[3207]               * end of the string will indicate a legal end of phrase if
[3208]               * it occurs before the usual indicator!
[3209]               ***********************************************************
[3210] B364 D6,4A,23 PHRASE CEQ  NUMBER,@CCHAR     Phrase start with #?
[3211] B367 53,9F           BR   GB370
[3212] B369 91,08           DINC @PTCCIS           Yes, inc CC ptr past #
[3213] B36B D6,B0,08 GB33C  CEQ  SPACE,V*PTCCIS    Skip spaces
       B36E 20
[3214] B36F 53,75           BR   GB346
[3215] B371 91,08           DINC @PTCCIS
[3216] B373 53,6B           BR   GB33C
[3217] B375 D6,B0,08 GB346  CEQ  NUMBER,V*PTCCIS   All spaces?
       B378 23
[3218] B379 53,7E           BR   GB34F
[3219] B37B 91,08           DINC @PTCCIS           Yes, skip this # too
[3220] B37D 00              RTN                    And ignore this phrase
[3221] B37E BD,0C,08 GB34F  DST  @PTCCIS,@PTFCIP   Save 1st char in phrase
[3222] B381 91,08    GB352  DINC @PTCCIS           Go on to next char
[3223]               * Got to watch for end of string. If encountered before a
[3224]               * #, act like char after string is #. Then last char will

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0056 
[3225]               * be char before, or the last char in the string!!
[3226] B383 C5,08,0A        DCH  @PTLCIS,@PTCCIS
[3227] B386 73,91           BS   FNDNUM
[3228] B388 BC,4A,B0        ST   V*PTCCIS,@CCHAR   No, get char in CCHAR
       B38B 08
[3229] B38C D6,4A,23        CEQ  NUMBER,@CCHAR     If not # continue looking
[3230] B38F 53,81           BR   GB352
[3231] B391 BD,10,08 FNDNUM DST  @PTCCIS,@PTLCIP   Last char in phrase is one
[3232] B394 93,10           DDEC @PTLCIP            before the #
[3233] B396 91,08           DINC @PTCCIS           Point to char after #
[3234] B398 06,B3,CB        CALL GETTIM            Get 1st timing char after phr
[3235] B39B 86,4B           CLR  @SPLFLG           Indicate don't spell
[3236] B39D 53,BA           BR   GB38B             No # as 1st char in phrase
[3237] B39F BD,0C,08 GB370  DST  @PTCCIS,@PTFCIP   Curr char is 1st char phrase
[3238] B3A2 86,4B           CLR  @SPLFLG           Assume don't spell
[3239] B3A4 CA,4A,41        CHE  >41,@CCHAR        If not alphabetic   (>41="A")
[3240] B3A7 73,AB           BS   GB37C
[3241] B3A9 90,4B           INC  @SPLFLG            set spell flag
[3242]               * Need to find end of phrase, which is char before next
[3243]               * timing char we find. Therefore, look for a timing char!
[3244] B3AB 91,08    GB37C  DINC @PTCCIS
[3245] B3AD 06,B3,CB        CALL GETTIM
[3246] B3B0 D6,51,FF        CEQ  >FF,@TIMLEN       If not timing, loop
[3247] B3B3 73,AB           BS   GB37C
[3248] B3B5 BD,10,08        DST  @PTCCIS,@PTLCIP   Char before curr char is
[3249] B3B8 93,10           DDEC @PTLCIP            the last char in phrase
[3250] B3BA 00       GB38B  RTN
[3251]               ***********************************************************
[3252]               * TIMING will loop through chars in string until it finds
[3253]               * non-timing char. Non-timing chars have TIMLEN values of
[3254]               * >FE or >FF. GETTIM must be called before this routine to
[3255]               * establish a correct value of TIMLEN. Also, most likely
[3256]               * TOTTIM should have been cleared.
[3257]               ***********************************************************
[3259] B3BE 73,CA           BS   GB39B
[3260] B3C0 A1,4C,51        DADD @TIMLEN,@TOTTIM
[3261] B3C3 91,08           DINC @PTCCIS
[3262] B3C5 06,B3,CB        CALL GETTIM
[3263] B3C8 53,BB           BR   TIMING
[3264] B3CA 00       GB39B  RTN
[3265]               ***********************************************************
[3266]               * GETTIM will examine the current char in the string and
[3267]               * set TIMLEN to the appropriate time delay value. TIMLEN
[3268]               * can take on the following values:
[3269]               *           >00 if char is timing '+'
[3270]               *           >06 if char is timing ' '
[3271]               *           >0C if char is timing '-'
[3272]               *           >12 if char is timing ','
[3273]               *           >1E if char is timing ';'
[3274]               *           >30 if char is timing ':'
[3275]               *           >3C if char is timing '.'
[3276]               *           >FE if char is out of stirng bounds
[3277]               *           >FF if char is not timing
[3278]               * Note that to test timing, some manipulation of PTCCIS
[3279]               * would be neccesary, so it is stored and used in TEMP1
[3280]               ***********************************************************
[3281] B3CB BC,4A,B0 GETTIM ST   V*PTCCIS,@CCHAR   Get the char
       B3CE 08
[3282] B3CF BD,54,08        DST  @PTCCIS,@TEMP1     store curr ptr in TEMP1
[3283] B3D2 C5,54,0A        DCH  @PTLCIS,@TEMP1     out of string bounds?
[3284] B3D5 53,DB           BR   GB3AC
[3285] B3D7 BE,51,FE        ST   >FE,@TIMLEN       Yes, load value and return
[3286] B3DA 00              RTN

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0057 
[3287] B3DB C6,4A,3B GB3AC  CH   SEMICO,@CCHAR     Can not be timing
[3288] B3DE 74,45           BS   NOTIME
[3289] B3E0 D6,4A,20        CEQ  SPACE,@CCHAR
[3290] B3E3 53,F4           BR   GB3C5
[3291] B3E5 BE,51,06        ST   6,@TIMLEN
[3292] B3E8 D6,E0,01 GB3B9  CEQ  SPACE,[email protected](@PTCCIS) While spaces
       B3EB 08,20
[3293] B3ED 53,F3           BR   GB3C4
[3294] B3EF 91,08           DINC @PTCCIS           Skip them
[3295] B3F1 53,E8           BR   GB3B9
[3296] B3F3 00       GB3C4  RTN
[3297] B3F4 D6,4A,2B GB3C5  CEQ  PLUS,@CCHAR
[3298] B3F7 54,03           BR   GB3D4
[3299] B3F9 91,54           DINC @TEMP1            Need to test the next char
[3300] B3FB 06,B4,49        CALL NUMERC            Is it numeric
[3301] B3FE 74,45           BS   NOTIME            Was numeric => not timing cha
[3302] B400 86,51           CLR  @TIMLEN           Not numeric => set as no timi
[3303] B402 00              RTN
[3304] B403 D6,4A,2C GB3D4  CEQ  COMMAT,@CCHAR
[3305] B406 54,0C           BR   GB3DD
[3306] B408 BE,51,12        ST   >12,@TIMLEN
[3307] B40B 00              RTN
[3308] B40C D6,4A,2E GB3DD  CEQ  PERIOD,@CCHAR
[3309] B40F 54,23           BR   GB3F4
[3310] B411 93,54           DDEC @TEMP1            Go back to preceding char
[3311] B413 06,B4,49        CALL NUMERC            Is it numeric?
[3312] B416 54,1F           BR   PTIME             No, so it is timing
[3313] B418 95,54           DINCT @TEMP1           Yes, on to following char
[3314] B41A 06,B4,49        CALL NUMERC            Is it numeric too?
[3315] B41D 74,45           BS   NOTIME            Yes, both numeric => not timi
[3316] B41F BE,51,3C PTIME  ST   >3C,@TIMLEN       Both not numeric  => timing
[3317] B422 00              RTN
[3318] B423 D6,4A,2D GB3F4  CEQ  HYPEN,@CCHAR
[3319] B426 54,33           BR   GB404
[3320] B428 91,54           DINC @TEMP1            Check next char
[3321] B42A 06,B4,49        CALL NUMERC            Is it numeric?
[3322] B42D 74,45           BS   NOTIME            Was numeric => not a timing c
[3323] B42F BE,51,0C        ST   >0C,@TIMLEN       Was not numeric => set as tim
[3324] B432 00              RTN
[3325] B433 D6,4A,3A GB404  CEQ  COLON,@CCHAR
[3326] B436 54,3C           BR   GB40D
[3327] B438 BE,51,30        ST   >30,@TIMLEN
[3328] B43B 00              RTN
[3329] B43C D6,4A,3B GB40D  CEQ  SEMICO,@CCHAR
[3330] B43F 54,45           BR   NOTIME
[3331] B441 BE,51,1E        ST   >1E,@TIMLEN
[3332] B444 00              RTN
[3333] B445 BE,51,FF NOTIME ST   >FF,@TIMLEN       Set as no timing char present
[3334] B448 00              RTN
[3335]               ***********************************************************
[3336]               * NUMERC tests the char pointed to by PTCCIS and verifies
[3337]               * the following:
[3338]               *  1 - it is within the current string boundaries
[3339]               *  2 - it is numeric (i.e. between '0' and '9')
[3340]               * If both of the above conditions are true, COND is set
[3341]               * upon return, otherwise COND is reset
[3342]               ***********************************************************
[3343] B449 C5,54,0A NUMERC DCH  @PTLCIS,@TEMP1
[3344] B44C 74,5F           BS   GB430
[3345] B44E C5,06,54        DCH  @TEMP1,@PTFCIS
[3346] B451 74,5F           BS   GB430
[3347] B453 CA,B0,54        CHE  >30,V*TEMP1
       B456 30
[3348] B457 54,5F           BR   GB430

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0058 
[3349] B459 C6,B0,54        CH   >39,V*TEMP1
       B45C 39
[3350] B45D 53,60           BR   SETCB
[3351] B45F 01       GB430  RTNC
[3352]               ***********************************************************
[3353]               * LOOKUP is a prolong routine to SEARCH. In each PHROM,
[3354]               * there may be 2 trees, one starting at >0000 and the other
[3355]               * at >8000. Either may or may not be present. Presences is
[3356]               * determined if a >AA byte is at the starting location.
[3357]               * LOOKUP determines if the tree at >0000 is in, and if so,
[3358]               * calls SEARCH with that addr. If that tree is not present
[3359]               * or the phrase couldn't be found in it, LOOKUP then checks
[3360]               * if the tree at >8000 is present, and again, if so, calls
[3361]               * SEARCH with that tree address. If the word was found in
[3362]               * the first tree, or after searching the second tree, the
[3363]               * routine will return.
[3364]               ***********************************************************
[3365] B460 87,66    LOOKUP DCLR @BYTE1            BYTE1 contains addr of curr t
[3366] B462 BD,12,66 TRYAGN DST  @BYTE1,@PTFBPH    Look for >AA tree header
[3367] B465 06,B5,1C        CALL LOADAD            LOADAD expects addr in PTFBPH
[3368] B468 BE,C0,00        ST   >10,@PAD(@WRITE)  Put out read byte command
       B46B 5A,10
[3369] B46D D6,C0,00        CEQ  >AA,@PAD(@READ)   Tree out there?
       B470 58,AA
[3370] B472 54,7D           BR   GB44E
[3371] B474 91,12           DINC @PTFBPH           Skip the tree header
[3372] B476 06,B4,88        CALL SEARCH            Go search this PHROM tree
[3373] B479 8F,4D           DCZ  @DATAAD           Phrase found => exit
[3374] B47B 54,87           BR   FOUND
[3375] B47D A3,66,80 GB44E  DADD >8000,@BYTE1      Go to start of next PHROM tre
       B480 00
[3376]               * Note >8000 + >8000 = >0000 => tried both trees
[3377] B481 8F,66           DCZ  @BYTE1
[3378] B483 54,62           BR   TRYAGN
[3379] B485 87,4D           DCLR @DATAAD           Didnt find phrase in either t
[3380] B487 00       FOUND  RTN
[3381]               ***********************************************************
[3382]               * SEARCH actually searches the PHROM tree for the phrase.
[3383]               * The PHROM tree organization is as follows:
[3384]               *        (i.e. this is one phrase node)
[3385]               *              phrase ASCII length      1 byte
[3386]               *              actual ASCII characters  n bytes
[3387]               *              less then pointer        2 bytes
[3388]               *              greater then pointer     2 bytes
[3389]               *              speech data pointer      3 bytes
[3390]               *              speech data length       1 byte
[3391]               * The comparison of two words proceeds on a char by char
[3392]               * basis, where length is secondary to char values, i.e.
[3393]               * move > answer; number < we; eight < eighty; etc...
[3394]               ***********************************************************
[3395] B488 06,B5,1C SEARCH CALL LOADAD            Set PHROM to start phrase nod
[3396] B48B BE,C0,00        ST   >10,@PAD(@WRITE)  Issue read byte command
       B48E 5A,10
[3397] B490 86,16           CLR  @PTLCPH           Length of phrase => PTLCPH
[3398] B492 BC,17,C0        ST   @PAD(@READ),@PTLCPH+1 (stored as 2 byte value
       B495 00,58
[3399] B497 A1,16,12        DADD @PTFBPH,@PTLCPH   Add front ptr giving end ptr
[3400] B49A BD,14,12        DST  @PTFBPH,@PTCCPH   Set up curr char as 1 beyond
[3401] B49D 91,14           DINC @PTCCPH            length byte
[3402] B49F BD,0E,0C        DST  @PTFCIP,@PTCCIP   Reset current ptr into phrase
[3403]               * Compare two characters
[3404] B4A2 BE,C0,00 NEXT   ST   >10,@PAD(@WRITE)  Issue read byte command
       B4A5 5A,10
[3405] B4A7 BC,5D,C0        ST   @PAD(@READ),@PHDATA Get char in from PHROM

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0059 
       B4AA 00,58
[3406] B4AC D4,5D,B0        CEQ  V*PTCCIP,@PHDATA  Compare the char
       B4AF 0E
[3407] B4B0 55,00           BR   GB4D1
[3408] B4B2 91,14           DINC @PTCCPH           Equal, advance both pointers
[3409] B4B4 91,0E           DINC @PTCCIP
[3410] B4B6 D6,B0,0E        CEQ  SPACE,V*PTCCIP    Skip extra spaces
       B4B9 20
[3411] B4BA 54,D0           BR   GB4A1
[3412] B4BC D6,E0,01 GB48D  CEQ  SPACE,[email protected](@PTCCIP) While spaces
       B4BF 0E,20
[3413] B4C1 54,C7           BR   GB498
[3414] B4C3 91,0E           DINC @PTCCIP           Skip them
[3415] B4C5 54,BC           BR   GB48D
[3416]               * By skipping extra spaces, might have reached end of phras
[3417]               * If this is true, next char in phrase = #. If so, advance
[3418]               * the pointer to be beyond end of phrase.
[3419] B4C7 D6,E0,01 GB498  CEQ  NUMBER,[email protected](@PTCCIP)
       B4CA 0E,23
[3420] B4CC 54,D0           BR   GB4A1
[3421] B4CE 91,0E           DINC @PTCCIP
[3422] B4D0 C5,14,16 GB4A1  DCH  @PTLCPH,@PTCCPH   End of PHROM word?
[3423] B4D3 54,F5           BR   GB4C6
[3424] B4D5 C5,0E,10        DCH  @PTLCIP,@PTCCIP   Yes, end of phrase
[3425] B4D8 54,EF           BR   GB4C0
[3426] B4DA BD,12,16        DST  @PTLCPH,@PTFBPH   Yes, word found
[3427]               * Skip 5 bytes down from last char to data pointer
[3428] B4DD A3,12,00        DADD 6,@PTFBPH
       B4E0 06
[3429] B4E1 06,B5,4E        CALL READAD            Set data addr => DATAAD
[3430] B4E4 BE,C0,00        ST   >10,@PAD(@WRITE)  Issue read byte command
       B4E7 5A,10
[3431] B4E9 BC,64,C0        ST   @PAD(@READ),@STRLEN Get length of speech data
       B4EC 00,58
[3432] B4EE 00              RTN
[3433] B4EF BF,12,00 GB4C0  DST  3,@PTFBPH         Move 3 bytes past PTLCPH
       B4F2 03
[3434] B4F3 55,0C           BR   NXTPHR
[3435] B4F5 C5,0E,10 GB4C6  DCH  @PTLCIP,@PTCCIP   2 characters
[3436] B4F8 54,A2           BR   NEXT
[3437] B4FA BF,12,00        DST  1,@PTFBPH         Phrase linger: use LT ptr
       B4FD 01
[3438] B4FE 55,0C           BR   NXTPHR
[3439]               * Two characters compared were not equal
[3440] B500 BF,12,00 GB4D1  DST  3,@PTFBPH         3 bytes past last to GT
       B503 03
[3441] B504 C4,5D,B0        CH   V*PTCCIP,@PHDATA  After phrase
       B507 0E
[3442] B508 55,0C           BR   NXTPHR
[3443] B50A 97,12           DDECT @PTFBPH          Back up 2 bytes to LT link
[3444]               * Go get next phrase out of the PHROM to compare
[3445] B50C A1,12,16 NXTPHR DADD @PTLCPH,@PTFBPH   Add displacement to last char
[3446] B50F 06,B5,4E        CALL READAD             and get the new address
[3447] B512 8F,4D           DCZ  @DATAAD           More leaves on this tree
[3448] B514 55,17           BR   GB4E8
[3449] B516 00              RTN                    No, return empty handed
[3450] B517 BD,12,4D GB4E8  DST  @DATAAD,@PTFBPH   Store new addr in PTFBPH
[3451] B51A 54,88           BR   SEARCH            Go compare this new word!
[3452]               * The program should never reach this point!! It should
[3453]               * return somewhere up above.
[3454]               ***********************************************************
[3455]               * LOADAD will set the addr out in the PHROM to the addr
[3456]               * found in PTFBPH. Note that the PHROM is expecting five
[3457]               * nybbles to be written out as the address.

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0060 
[3458]               ***********************************************************
[3459] B51C BD,54,12 LOADAD DST  @PTFBPH,@TEMP1    This is destructive, so copy
[3460] B51F BD,56,12        DST  @PTFBPH,@TEMP2     address into temporary areas
[3461] B522 E6,54,04        SRL  4,@TEMP1          Isolate the MSN of the MSB
[3462] B525 E6,55,04        SRL  4,@TEMP1+1        Isolate the MSN of the LSB
[3463] B528 B3,56,0F        DAND >0F0F,@TEMP2      Isolate the LSN of the MSB, L
       B52B 0F
[3464] B52C B7,54,40        DOR  >4040,@TEMP1      Include a 4 as MSN of all 4 n
       B52F 40
[3465] B530 B7,56,40        DOR  >4040,@TEMP2       to indicate a Load Address C
       B533 40
[3466] B534 BC,C0,00        ST   @TEMP2+1,@PAD(@WRITE) Write out the LSN of th
       B537 5A,57
[3467] B539 BC,C0,00        ST   @TEMP1+1,@PAD(@WRITE) Write out the LSN of th
       B53C 5A,55
[3468] B53E BC,C0,00        ST   @TEMP2,@PAD(@WRITE)   Write out the MSN of th
       B541 5A,56
[3469] B543 BC,C0,00        ST   @TEMP1,@PAD(@WRITE)   Write out the MSN of th
       B546 5A,54
[3470] B548 BE,C0,00        ST   >40,@PAD(@WRITE)      Write out 0 as fifth ny
       B54B 5A,40
[3471] B54D 00              RTN
[3472]               ***********************************************************
[3473]               * READAD will read an address from the PHROM and store it
[3474]               * in DATAAD. Note that PTFBPH should contain the addr of
[3475]               * the PHROM location to be read so LOADAD will work.
[3476]               ***********************************************************
[3477] B54E 06,B5,1C READAD CALL LOADAD            Set the addr of the PHROM
[3478] B551 BE,C0,00        ST   >10,@PAD(@WRITE)  Get high byte of addr
       B554 5A,10
[3479] B556 BC,4D,C0        ST   @PAD(@READ),@DATAAD Store it in DATAAD
       B559 00,58
[3480] B55B BE,C0,00        ST   >10,@PAD(@WRITE)  Get low byte of addr
       B55E 5A,10
[3481] B560 BC,4E,C0        ST   @PAD(@READ),@DATAAD+1 Store it in DATAAD+1
       B563 00,58
[3482] B565 00              RTN
[3483]               ***********************************************************
[3484]               * STDATA will store the data in DATAAD and TOTTIM onto the
[3485]               * speech list. It will also check that there is room on the
[3486]               * speech list for this entry, and abort with error if not.
[3487]               ***********************************************************
[3488] B566 D5,02,04 STDATA DCEQ @PTEBSL,@PTLBSL   Is there room?
[3489] B569 75,88           BS   ERRSSL
[3490] B56B 35,00,03        MOVE 3,@TOTTIM,V*PTLBSL   Put data in list
       B56E B0,02,4C
[3491] B571 A3,02,00        DADD 3,@PTLBSL              and inc top of list
       B574 03
[3492] B575 00              RTN
[3493]               ***********************************************************
[3494]               * WAIT loops until the speech peripheral goes idle.
[3495]               ***********************************************************
[3496]               *    ( Loop until nobody is talking)
[3497] B576 BC,69,C0 WAIT   ST   @PAD(@READ),@SPKSTS  Read status from PHROM
       B579 00,58
[3498] B57B DA,69,80        CLOG >80,@SPKSTS
[3499] B57E 55,76           BR   WAIT
[3500] B580 00              RTN
[3501]               ***********************************************************
[3502]               * SETRW moves addrs of speech read/write from GROM to VDP
[3503]               ***********************************************************
[3504] B581 31,00,04 SETRW  MOVE 4,[email protected]>0046,@READ
       B584 58,00,46
[3505] B587 00              RTN

99/4 GPL-ASSEMBLER (Pass 3) correct                                   PAGE 0061 
[3506]               ***********************************************************
[3507]               *                    ERROR MESSAGES
[3508]               ***********************************************************
[3509]               *      The following calls are in EXECS file.
[3510]               * ERRSYN CALL ERRZZ           * SYNTAX ERROR
[3511]               *        BYTE 3
[3512]               * ERRSNM CALL ERRZZ           * STRING-NUMBER MISMATCH
[3513]               *        BYTE 7
[3514]               * ERRBV  CALL ERRZZ           * BAD VALUE
[3515]               *        BYTE 30
[3516]               * ERRIAL CALL ERRZZ           * INCORRECT ARGUMENT LIST
[3517]               *        BYTE 31
[3518]               ***********************************************************
[3519] B588 06,6A,84 ERRSSL  CALL ERRZZ          * SPEECH STRING TOO LONG
[3520] B58B 15               BYTE 21
[3521]               ***********************************************************


  • Thanks 1

Share this post

Link to post
Share on other sites
On 2/9/2022 at 8:48 AM, wierd_w said:

That wasn't allophone speech.  Those were LPC samples.  TI's original TI Trek loads all its LPC (even where samples are identical to those in ROM, which they often are) from disk as needed, and my remake functions identically (just with newly sourced/encoded samples).  That's supported by CALL SAY (in its mostly-but-not-quite-identical Speech Editor and Extended BASIC versions).  CALL SAY offers no support for allophone speech,  however. 

  • Like 1

Share this post

Link to post
Share on other sites
17 minutes ago, pixelpedant said:

That wasn't allophone speech.  Those were LPC samples.  TI's original TI Trek loads all its LPC (even where samples are identical to those in ROM, which they often are) from disk as needed, and my remake functions identically (just with newly sourced/encoded samples).  That's supported by CALL SAY (in its mostly-but-not-quite-identical Speech Editor and Extended BASIC versions).  CALL SAY offers no support for allophone speech,  however. 

Would not be hard for me to put the 4K of Allophones into XB. Or add the TE2 stuff.

Share this post

Link to post
Share on other sites

I may have shared this before, since I see I put notes in it and it's already zipped, but some years ago I started reverse engineering the XB Text to Speech disk, with an eye to being able to store the program on a bank switched cartridge and so use text to speech in new games.


I never know anymore what I'll get to finish, so here's the work-in-progress. It's reasonably far along. I was very sure I had a plan for how to make it work, and it would take three 8k pages in the cartridge. But no work on building those pages is yet done.




  • Like 3
  • Thanks 2

Share this post

Link to post
Share on other sites

@Tursi ...Sweet, all those notes and commented disassembly. I'm writing numbers on old envelopes and then trying to remember why.:ponder:

So as long as we're sharing...


I came up with a nouveau approach last-night. It goes a little something like this... I setup XB110, to use FG99's, GRAM option, and upper 4K page switching with RAM... I replaced the lower 4K ROM on page 2 with TE-II's 4K ROM, and added speech DATABASE GROM 7. The plan is to use CALL LINK, to run a stub program that will page in the speech ROM, branch to some code that I'll place in what appears to be 510, bytes of free space at it's end... from there I'll save the GROM return address... swap XB's, GRAM 6, with TE-II's, speech DATABASE GROM 6... call the SPEAK routine... when it returns, I'll swap XB's, GROM 6, back in , restore the GROM return address, return to the stub program... restore the lower ROM page, and return from CALL LINK.


But for all that to work, I'll need to CALL LINK, to XLAT, first. Before I can do that, I'll need to find a way to get XLAT, to swallow the text string... one of life's little mysteries. I think it's using INDEXED REGISTERS ...not yet too familiar with that.


  P.S. I can only give this a little time here and there, could be a while, or never.
        Feel free to take the torch and run!


  P.P.S. I still haven't been able to test this re-worked version of XB, thoroughly.

           Please let me know if you find that it has issues.:-o

XB 110 with RAM and prelim speech test layout for FG99.rar

  • Like 2

Share this post

Link to post
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.

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.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...