

' when using this program be sure to use the qbasic/h option to get the best
'  veiw of the source code
'



DECLARE SUB ZEROMIC ()
DECLARE SUB MICNOISE (BT!)
DECLARE SUB verbal ()
DECLARE SUB phonix (phr$)
DECLARE SUB happy ()
DECLARE SUB sad ()
DECLARE SUB GetWords (length%(), Saved%())
DECLARE SUB Compare (y%, yp%, Sample%(), Saved%(), length%(), Score%(), samplen%, SampleTmp%())
DECLARE FUNCTION GetBlasterAddr% ()
DECLARE FUNCTION SBreset% ()
'
DECLARE SUB MOUSE (which)

DECLARE SUB mousep (joyh, joyv, JHCENT, JVCENT, BU1, bu2, BC, H1, V1, DLY, DLC)
DECLARE SUB CALIBRATEJOY (JHCENT, JVCENT, DLY)
DECLARE SUB joystk (joyh, joyv, JHCENT, JVCENT, BU1, bu2, BC, H1, V1, DLY, DLC)
'                   JOYH, JOYV, JHCENT, JVCENT, bu1, bu2, BC, H1, V1, DLY, DLC
DECLARE SUB advance ()
DECLARE SUB deadvance ()
DECLARE SUB playwav (wavefile$)
DECLARE SUB ValidWavHeader (file$, LenHeader%, dataLen&, nChannels%, nSamplesPerSec&, nAvgBytesPerSec&, ok%)
DECLARE SUB WriteToDSP (v%)
DECLARE SUB PlayBack (buffer$, size%, freq&, BytesPerSec&, chans%, NUM%)
DECLARE SUB delay (tdelay!)
DECLARE SUB SPEAK (phr$)
DECLARE FUNCTION GetBlasterAddr% ()
DECLARE FUNCTION SBreset% ()
COMMON SHARED BlasterAddr%, dma%, repeats%

CONST baseaddr1 = &H220
CONST CommAddr = baseaddr1 + &HC, DataAddr = baseaddr1 + &HA
CONST ResetAddr = baseaddr1 + &H6




DIM SHARED mouser$, MOUSELEFTBUTTON, mouserightbutton, mousexpos, mouseypos, AX%, bx%, cx%, dx%


SCREEN 8
CLEAR 33000
     CLS
     CLEAR 20000
     DIM pa$(200)
OUT ResetAddr, 1        'RESETS THE
OUT ResetAddr, 0        'SOUND BLASTER

ON ERROR GOTO 30000


menucolor = 4
tc = 1
     INPUT "do you have joysticks <j> or mouse <M>?"; joyyn$
    
     IF joyyn$ = "J" THEN

       joystkpresent = 1
       ELSE

       joystkpresent = 0
     END IF


     IF joystkpresent = 1 THEN
     CALL CALIBRATEJOY(JHCENT, JVCENT, DLY)
     END IF
    
     IF joyyn$ = "M" THEN

MOUSE 0
MOUSE 4
DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B
DATA 5E,08,8B,0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53
DATA 8B,5E,0C,89,07,58,8B,5E,0A,89,07,8B,5E,08,89,0F
DATA 8B,5E,06,89,17,5D,CA,08,00

' ==========================================
      mpresent = 1
      ELSE
      mpresent = 0
     END IF
COLOR 1, 6
joyh = (80 / 2)
joyv = (22 / 2)
V1 = joyv: H1 = joyh

     CALL ZEROMIC
     CALL ZEROMIC


6000  REM THIS IS A WORD PROCESSING PROGRAM WRITTEN BY SCOTT GATES ,INC 1995.
     donte = 0
     LOCATE 9, 11: PRINT "coded February 8 1999"
     LOCATE 10, 10: PRINT "WELCOME TO TALKTYPE 1999,": LOCATE 11, 11: PRINT "BY SCOTT GATES INC."
     LOCATE 12, 12: PRINT "PRESS <S> TO START."
     LOCATE 13, 13: PRINT "<I> for instructions."
6040 KE$ = INKEY$: KE$ = UCASE$(KE$)
     CALL MICNOISE(BYTE)
     LOCATE 1, 1: PRINT BYTE; "  "
     IF KE$ = "S" OR BYTE < 128 - 2 OR BYTE > 128 + 2 THEN 6070
     IF KE$ = "I" THEN GOSUB 20000: GOTO 6000
     IF KE$ = "B" THEN PRINT "BACKING UP TYPER": REM SAVE "TYPER": PRINT "DONE": BEEP
   
     GOTO 6040
6070 SOUND 2000, 3
     CALL ZEROMIC
     X = 1

     
6130 CLS
    
     LOCATE 2, 1
     PRINT " THEN PRESS </> WHEN FINISHED. LS<"; pl; "> Page {"; X; "}"; "total pgs ["; xl; "]"
     PRINT ":"
     PRINT pa$(X);

WHILE donte = 0


'PA$(x) will be built in this procedure <<////
     LOCATE 1, 1
PRINT "File"
    
     LOCATE 2, 1
     PRINT " <<< LS<"; pl; "> Page {"; X; "}"; "total pgs ["; xl; "]"
     PRINT ":"
     PRINT pa$(X);
KE$ = INKEY$


''~~~~~ Rem arrow key handler ~~~~
IF LEN(KE$) > 1 THEN
lf$ = LEFT$(KE$, 1)
rg$ = RIGHT$(KE$, 1)
lf = ASC(lf$)
rg = ASC(rg$)
IF lf = 0 AND rg$ = "M" THEN joyh = joyh + 1

IF lf = 0 AND rg$ = "P" THEN joyv = joyv + 1

IF lf = 0 AND rg$ = "K" THEN joyh = joyh - 1

IF lf = 0 AND rg$ = "H" THEN joyv = joyv - 1


IF lf = 0 AND rg = 134 THEN CALL SPEAK(pa$(X))

IF lf = 0 AND rg$ = ";" THEN 6220
lf = 1
KE$ = ""
GOTO 6130
END IF '~~~~~end of arrow key

 IF joystkpresent = 1 THEN
   CALL joystk(joyh, joyv, JHCENT, JVCENT, BU1, bu2, BC, H1, V1, DLY, DLC) ' rem get the joystick values
    COLOR tc
 END IF

 IF mpresent = 1 THEN

 CALL mousep(joyh, joyv, JHCENT, JVCENT, BU1, bu2, BC, H1, V1, DLY, DLC)
 COLOR tc
 END IF


 IF KE$ = CHR$(13) THEN 'rem advance the page
  X = X + 1: CALL advance
   IF X > (xl) THEN xl = X
    GOTO 6130


 END IF
 IF KE$ = CHR$(27) THEN ' decrement to the previous page
 IF X >= 1 THEN X = X - 1: CALL deadvance: GOTO 6130 ELSE FOR llp = 0 TO 3: CALL deadvance: NEXT llp
 IF X > (xl) THEN xl = X: pa$(0) = STR$(xl)
 KE$ = ""
 END IF



 IF KE$ = CHR$(8) THEN
  size = LEN(pa$(X))
  IF size > 0 THEN frag$ = LEFT$(pa$(X), (size - 1)): pa$(X) = frag$: pl = pl - 1: KE$ = "": GOTO 6130 ELSE SOUND 300, .5
  KE$ = ""
 END IF


IF KE$ <> "" THEN pa$(X) = pa$(X) + KE$: pl = pl + 1: PRINT KE$; : SOUND 2000, .05
 


WEND
    
     
     
     
     pa$(X) = pa$(X) + pa$: pa$(0) = STR$(X)
     PRINT pa$(X)
     GOTO 6130


6190 IF X > (xl) THEN xl = X: pa$(0) = STR$(xl)


     FOR y = 1 TO (xl)
     PRINT y; " "; pa$(y)
     NEXT y

     'COLOR 1, menucolor
6220 PRINT "<<<< MENU >>>>>"
     PRINT "PRESS <P> TO PRINT,<S> TO SAVE,<L> TO LOAD,<R> TO RETURN"
     PRINT "TO TYPING,<N> TO START A NEW FILE,<E> TO EDIT A LINE"
     PRINT "AND <D> TO RETURN TO DOS.<B> RETURNS YOU TO START."
     PRINT "<K> TO DELETE A NUMBER <READ> WILL READ THE LETTER"
     PRINT " <I> for instructions"
     LINE INPUT CH$: IF CH$ = "" THEN SOUND 255, 4: GOTO 6220
     CH$ = UCASE$(CH$)
    
    
     IF CH$ = "B" OR CH$ = "b" THEN CHDIR "C:\UTIL": RUN "START"
6240 IF CH$ = "DIR" THEN FILES: INPUT "NEW DIRECTORY"; DIR$: IF DIR$ = "" THEN 6250 ELSE CHDIR DIR$: GOTO 6240
6250 IF CH$ = "K" THEN INPUT "NUMBER OF LINE TO BE DELETED"; NU: IF NU < 1 OR NU > (X) THEN PRINT "OUT OF RANGE": SOUND 200, 5:  ELSE PRINT pa$(NU): INPUT "IS THIS THE LINE YOU WANT TO ERASE? "; YN$: IF YN$ = "Y" OR YN$ = "YES" THEN pa$(NU) = "": IF NU = (X) THEN X = X - 1: GOTO 6220
     IF CH$ = "P" THEN CLS : FOR YY = 1 TO VAL(pa$(0)): PRINT pa$(YY): LPRINT pa$(YY): NEXT YY: PRINT "DONE": SOUND 255, 4: GOTO 6220
     IF CH$ = "S" THEN LINE INPUT "NAME OF FILE TO BE SAVED."; NA$: IF NA$ = "" THEN BEEP: GOTO 6220 ELSE OPEN "O", #1, NA$: pa$(0) = STR$(xl): PRINT #1, pa$(0): FOR Y1 = 1 TO xl: PRINT #1, pa$(Y1): NEXT Y1: CLOSE #1: PRINT "DONE": SOUND 255, 4
     IF CH$ = "R" THEN FOR Y3 = 1 TO (xl): PRINT pa$(Y3): NEXT Y3: KE$ = "": GOTO 6130
     IF CH$ = "EDIT" OR CH$ = "E" THEN 6380
     IF CH$ = "D" THEN CHDIR "C:\": PRINT "RETURNING TO DOS": SYSTEM
     IF CH$ = "N" THEN PRINT "EXISTING DATA DELETED.": SOUND 360, 10: GOTO 6000
     IF CH$ = "C" THEN INPUT "TYPE IN LETTER OF DRIVE YOU WANT TO USE."; dr$: CHDIR dr$ + ":\TYPER": PRINT "SWITCH TO "; dr$; " DRIVE AT TYPER"
     IF CH$ = "START" THEN CHDIR "C:\UTIL": RUN "START"
     IF CH$ = "program" OR CH$ = "PROGRAM" THEN CLS : CHDIR "C:\UTIL": KEY ON: LOCATE 1, 1: PRINT "YOU MAY NOW BEGIN TO PROGRAM SCOTT.": SOUND 3000, 2: END
     IF CH$ = "FONT" THEN 7000
     IF CH$ = "LOAD" OR CH$ = "L" THEN PRINT " DOCUMENT LOAD SECTION": GOSUB 8010
     IF CH$ = "READ" THEN 10010
     IF CH$ = "I" THEN GOSUB 20000: GOTO 6220
    
     IF CH$ = "TC" THEN

      INPUT "text color"; tc
      COLOR tc
    
     END IF
    
     IF CH$ = "BC" THEN

      INPUT "background border color"; BC
      COLOR , BC
   
     END IF
    
    
    
    
     GOTO 6220
6380 INPUT "ENTER LINE NUMBER TO BE EDITED."; LN: IF LN < 0 OR LN > X THEN SOUND 2000, 5: PRINT "THAT LINE DOES NOT EXIST.": GOTO 6380
     PRINT pa$(LN): PRINT "TYPE IN REPLACEMENT LINE FOR "; LN: LINE INPUT "REPLACEMENT"; pa$
     IF pa$ = "" THEN PRINT "NO REPLACEMENT MADE": GOTO 6190
     pa$(LN) = pa$
     GOTO 6190
     END
7000 INPUT "WHAT KIND OF FONT <ITALIC>,<MICROFONT>,<BOLD>"; FONT$
     REM
     IF FONT$ = "ITALIC" THEN LPRINT CHR$(27); CHR$(66): PRINT "SET TO ITALIC": REM ITALIC
     IF FONT$ = "MICROFONT" THEN LPRINT CHR$(27); CHR$(77): PRINT "SET TO MICROFONT": REM MICROFONT
     IF FONT$ = "BOLD" THEN LPRINT CHR$(27); CHR$(31); Z
     IF FONT$ = "ELONGATED" THEN LPRINT CHR$(27); CHR$(14)
     PRINT "DONE": GOTO 6220
     END
8010 DO
 PRINT "PICK YOUR DIRECTORY AND OR DRIVE <USE CORRECT DOS TERMINOLOGY> IF THIS DRIVE IS CORRECT THEN JUST HIT ENTER."
 INPUT "<-> when done."; dr$: IF dr$ <> "" THEN LD$ = dr$
      IF dr$ = CHR$(13) THEN 8010
     
      IF dr$ = "-" THEN 9000
     
      dr$ = UCASE$(dr$)

        
       IF dr$ <> "" THEN
       SHELL dr$
       END IF
      LOOP
9000    REM LOADING ALGORITHM
10000    INPUT "NAME OF MICROSOFTWORD DOCUMENT TO LOAD INTO TYPER"; DOCUMENT$
     IF DOCUMENT$ = "" THEN BEEP: INPUT "GO BACK TO MAIN MENU <M> OR CONTINUE <C>"; cho$
     cho$ = UCASE$(cho$)
     IF cho$ = "C" THEN GOTO 10000
     IF cho$ = "M" THEN cho$ = "": GOTO 6220
      CLOSE #1
      LINECOUNT = 1
        PRINT "OPENING-"; DOCUMENT$
        ON ERROR GOTO 30000

       OPEN DOCUMENT$ FOR INPUT AS #1
     DO
        LINE INPUT #1, pa$(LINECOUNT)
        PRINT pa$(LINECOUNT)
         LINECOUNT = LINECOUNT + 1
    LOOP UNTIL (EOF(1))
    CLOSE #1
 xl = LINECOUNT
      RETURN

10010 REM SPEAK LOOP
CALL ZEROMIC
PRINT "REMEMBER YOU CAN HIT <X> TO EXIT ANYTIME"

FOR X = 0 TO xl
pa$ = pa$(X)
KE$ = INKEY$: KE$ = UCASE$(KE$)
IF KE$ = "X" THEN 6220
PRINT
PRINT X; "- "; pa$

CALL ZEROMIC
CALL verbal
PRINT X; "- "; pa$

CALL SPEAK(pa$)
CALL ZEROMIC

NEXT X
PRINT " DONE SPEAKING"
GOTO 6220

20000 REM instructions
CALL ZEROMIC

   
PRINT
PRINT
PRINT
PRINT "   TalkType instructions"
PRINT "  Written by Scott Gates"
PRINT "E-mail <swg3681@ircc.net>"
PRINT "When in the typing area use the enter key to advance to the next page."
PRINT "<Esc> moves you to the previous page."
PRINT "use </> to bring up the menu "
PRINT " if you have stereo pc speakers you can make talktype read your letter."
PRINT " just type <READ> at the menu"
PRINT
PRINT " hit <R> to go back to talktype..."
KE$ = ""

CALL MICNOISE(BYTE)
WHILE KE$ <> "R" OR BYTE = 128

KE$ = INKEY$
KE$ = UCASE$(KE$)
WEND
   
RETURN

GOTO 20000

30000 PRINT "[error] ": BEEP

PRINT " an ambiegunes function has caused an error --->;"
PRINT "hit <R> "
PRINT dr$





DO
KE$ = INKEY$

IF KE$ = CHR$(27) THEN RUN



LOOP UNTIL KE$ = "R"


RESUME

END




SCREEN 12

OUT ResetAddr, 1        'RESETS THE
OUT ResetAddr, 0        'SOUND BLASTER

DIM Sample(0 TO 200), length(0 TO 1), Saved(0 TO 1, 0 TO 100)
DIM Score(0 TO 2), SampleTmp(0 TO 200), start(6)

CALL SPEAK("Y")
DO
        OUT CommAddr, &H20
        BYTE = INP(DataAddr)
  IF KE$ = "T" THEN CALL SPEAK("T")
LOCATE 1, 1: PRINT BYTE; "  "
     KE$ = INKEY$
LOOP UNTIL KE$ = "S"

30 REM main loop
     
CALL verbal
  c = c + 1: IF c > 12 THEN c = 1
  CIRCLE (h, v), 30, c: PAINT (h, v), c
  h = INT(RND(1) * (455)) + 1

  v = INT(RND(1) * (355)) + 1


 SPEAK ("NEXT")
FOR DLR = 0 TO 20
PRINT DLR
NEXT DLR
KE$ = INKEY$

IF KE$ = "S" THEN CALL SPEAK("NEXT")

'speak ("ok")
'SLEEP
40 GOTO 30
'CALL GetWords(length(), Saved())
SCREEN 9, 0, 1

CLS
delay1 = 20
Linedelay = 50
Starty = 0
y = 100
Sct = 0
yp = 4
COLOR 15
END

SUB advance

FOR ssx = 0 TO 3000 STEP 200
SOUND 100 + ssx, .05
NEXT ssx

END SUB

SUB CALIBRATEJOY (JHCENT, JVCENT, DLY)
CLS
PRINT "center joystick and hit (j)"
DO
KE$ = INKEY$
KE$ = UCASE$(KE$)
LOCATE 5, 5
PRINT JHCENT, JVCENT
JHCENT = STICK(0)
JVCENT = STICK(1)

LOOP UNTIL KE$ = "J" OR STRIG(0) = -1



INPUT "PLEASE GIVE ME THE DELAY ..."; DLY

CLS








END SUB

SUB deadvance
sxx = 3000
FOR sxx = 3000 TO 1 STEP -200

SOUND 100 + sxx, .05
NEXT sxx

END SUB

DEFINT A-Z
'------------------------------------------------------------------------------
SUB delay (tdelay!)
time1! = TIMER
DO
LOOP WHILE (TIMER - time1! < tdelay!) OR (time1! > TIMER)
END SUB

'------------------------------------------------------------------------------
FUNCTION GetBlasterAddr%
'Get Blaster Address and DMA channel from Environment Variable
tmp% = 0  'No Environment Variable Set...default
blast$ = UCASE$(ENVIRON$("BLASTER"))
IF LEN(blast$) THEN
   tmp% = INSTR(blast$, "A")
   tmp1$ = MID$(blast$, tmp% + 1, 3)
   tmp% = VAL("&H" + tmp1$)
   IF tmp% = 203 THEN tmp% = -1    'If there is no value assigned
   IF tmp% > 0 THEN
      tmp2% = INSTR(blast$, "D")
      dma% = VAL(MID$(blast$, tmp2% + 1))        'dma% is a global variable
      IF dma% < 0 OR dma% > 7 THEN tmp% = -2
   END IF
END IF
GetBlasterAddr% = tmp%
END FUNCTION

DEFSNG A-Z
SUB joystk (joyh, joyv, JHCENT, JVCENT, BU1, bu2, BC, H1, V1, DLY, DLC)

'joyh is the horozontal position
'joyv is the verticle positon
'jh1,jv1 last place
'bu1 \___button values
'bu2 /
 arw$ = "TA 0G 2R 2D 2R 2U 2R 2H 2L 2TA0"


 DLC = DLC + 1
IF DLY >= (DLC) THEN
nul = STICK(0)
h = STICK(0)
v = STICK(1)
IF h > (JHCENT + 30) THEN joyh = joyh + 1

IF v > (JVCENT + 30) THEN joyv = joyv + 1

IF h < (JHCENT - 30) THEN joyh = joyh - 1

IF v < (JVCENT - 30) THEN joyv = joyv - 1
DLC = 0
END IF
 'LOCATE 15, 10: PRINT JOYH, JOYV



IF joyh < 1 THEN joyh = 1
IF joyv < 1 THEN joyv = 1
IF joyh > 79 THEN joyh = 79
IF joyv > 23 THEN joyv = 23
 IF H1 = 0 THEN H1 = joyh
 IF V1 = 0 THEN V1 = joyv
  c = INT(RND(1) * (12))
COLOR c
LOCATE joyv, joyh: PRINT CHR$(219);



IF V1 <> (joyv) OR H1 <> (joyh) THEN

LOCATE V1, H1
         
PRINT " ";

H1 = joyh
V1 = joyv
END IF

LOCATE 1, 1
END SUB

SUB MICNOISE (BYTE)

        OUT CommAddr, &H20
        BYTE = INP(DataAddr)

END SUB

'
SUB MOUSE (which)
'0 = Mouse Init
'1 = Mouse Driver
'2 = Mouse Put
'3 = Mouse Status
'4 = Mouse Hide
'5 = Mouse Show
IF which = 0 THEN
  mouser$ = SPACE$(57)
  FOR I% = 1 TO 57
    READ a$
    h$ = CHR$(VAL("&H" + a$))
    MID$(mouser$, I%, 1) = h$
  NEXT I%
  AX% = 0
  bx% = 0
  cx% = 0
  dx% = 0
  MOUSE 1
  MouseInit% = AX%
  MOUSE 5
END IF
IF which = 1 THEN
  DEF SEG = VARSEG(mouser$)
  mouser% = SADD(mouser$)
  CALL Absolute(AX%, bx%, cx%, dx%, mouser%)
END IF
IF which = 2 THEN
  AX% = 4
  cx% = X%
  dx% = y%
  bx% = 0
  MOUSE 1
END IF
IF which = 3 THEN
  AX% = 3
  MOUSE 1
  MOUSELEFTBUTTON = ((bx% AND 1) <> 0)
  mouserightbutton = ((bx% AND 2) <> 0)
  mousexpos = cx%
  mouseypos = dx%
END IF
IF which = 4 THEN
 AX% = 2
 bx% = 0
 cx% = 0
 dx% = 0
 MOUSE 1
END IF
IF which = 5 THEN
  AX% = 1
  bx% = 0
  cx% = 0
  dx% = 0
  MOUSE 1
END IF



END SUB

SUB mousep (joyh, joyv, JHCENT, JVCENT, BU1, bu2, BC, H1, V1, DLY, DLC)

'joyh is the horozontal position
'joyv is the verticle positon
'jh1,jv1 last place
'bu1 \___button values
'bu2 /
 arw$ = "TA 0G 2R 2D 2R 2U 2R 2H 2L 2TA0"

MOUSE (3)
joyh = mousexpos
joyv = mouseypos
IF MOUSELEFTBUTTON = -1 THEN
BU1 = 1
ELSE BU1 = 0
END IF

 'LOCATE 15, 10: PRINT JOYH, JOYV



IF joyh < 1 THEN joyh = 1
IF joyv < 1 THEN joyv = 1
IF joyh > 79 THEN joyh = 79
IF joyv > 23 THEN joyv = 23
 IF H1 = 0 THEN H1 = joyh
 IF V1 = 0 THEN V1 = joyv
  c = INT(RND(1) * (12))
COLOR c
LOCATE joyv, joyh: PRINT CHR$(219);



IF V1 <> (joyv) OR H1 <> (joyh) THEN

LOCATE V1, H1
        
PRINT " ";

H1 = joyh
V1 = joyv
END IF

LOCATE 1, 1







LOCATE 1, 1
END SUB

DEFINT A-Z
'------------------------------------------------------------------------------
SUB PlayBack (buffer$, size%, freq&, BytesPerSec&, chans%, NUM%)
size% = size% - 1
segment& = VARSEG(buffer$)
offset& = SADD(buffer$)
IF segment& < 0 THEN segment& = segment& + 65536
IF offset& < 0 THEN offset& = offset& + 65536
baseaddr& = segment& * 16 + offset&
look1% = VARPTR(baseaddr&)
look2% = VARPTR(size%)
SELECT CASE dma%
   CASE 0
      dmapage% = &H87   '135 decimal
      dmaaddr% = 0
      dmalen% = 1
   CASE 1
      dmapage% = &H83   '131 decimal
      dmaaddr% = 2
      dmalen% = 3
   CASE 2
      dmapage% = &H81
      dmaaddr% = 4
      dmalen% = 5
   CASE 3
      dmapage% = &H82
      dmaaddr% = 6
      dmalen% = 7
   CASE 4
      dmapage% = &H8F
      dmaaddr% = &HC0
      dmalen% = &HC2
   CASE 5
      dmapage% = &H8B
      dmaaddr% = &HC4
      dmalen% = &HC6
   CASE 6
      dmapage% = &H89
      dmaaddr% = &HC8
      dmalen% = &HCA
   CASE 7
      dmapage% = &H8A
      dmaaddr% = &HCC
      dmalen% = &HCE
END SELECT
SELECT CASE dma%
   CASE 0 TO 3
      dmamask% = &HA
      dmamode% = &HB
      dmaclear% = &HC
      dmastatus% = &H8
   CASE 4 TO 7
      dmamask% = &HD4
      dmamode% = &HD6
      dmaclear% = &HD8
      dmastatus% = &HD0
END SELECT
SELECT CASE dma%
   CASE 0, 4
      dmaterminal% = 1   'bit 0 of status register (&H08 or &HD0)
   CASE 1, 5
      dmaterminal% = 2   'bit 1
   CASE 2, 6
      dmaterminal% = 4   'bit 2
   CASE 3, 7
      dmaterminal% = 8   'bit 3
END SELECT

OUT dmamask%, dma% + 4   'mask the dma channel
OUT dmaclear%, &H0       '(clear the internal DMA flip/flop)
OUT dmamode%, 72 + dma%  '  72=010010XX where XX=dmachannel%
OUT dmaaddr%, PEEK(look1%)      'bits 0-7 of  the 20bit address
OUT dmaaddr%, PEEK(look1% + 1)  'bits 8-15 of the 20bit address
OUT dmapage%, PEEK(look1% + 2)  'bits 16-19 of the 20 bit address
OUT dmalen%, PEEK(look2%)       'bits 0-7 of size%
OUT dmalen%, PEEK(look2% + 1)   'bits 8-15  of size%
OUT dmamask%, dma%              'enable channel

IF NUM% = 1 THEN  'only need to Write out time constant once
   timeconst% = 256 - 1000000 / (freq& * chans%)
   CALL WriteToDSP(&H40)
   CALL WriteToDSP(timeconst%)
   'Reset Mixer    DSPmixeraddress = Blasteraddr% + &H4
   OUT BlasterAddr% + &H4, &H0
   OUT BlasterAddr% + &H4 + 1, 0
   'Set Volume to Maximum...255
   OUT BlasterAddr% + &H4, &H22
   OUT BlasterAddr% + &H4 + 1, 255
   IF chans% = 2 THEN
      'Set mixer to Stereo Output
      OUT BlasterAddr% + &H4, &HE
      OUT BlasterAddr% + &H4 + 1, 34      '34=2^5+2^1
   END IF
END IF
IF BytesPerSec& > 22000 THEN
   CALL WriteToDSP(&H48)   'Set Block Size
ELSE
   CALL WriteToDSP(&H14)   'DMA Mode 8-bit DAC
END IF
CALL WriteToDSP(PEEK(look2%))      'Lo byte of address
CALL WriteToDSP(PEEK(look2% + 1))  'High byte of address
IF BytesPerSec& > 22000 THEN CALL WriteToDSP(&H91)  'High Speed DMA mode 8-bit
dummy% = INP(dmastatus%)    'Read status byte once to make sure DMA is going.
WAIT dmastatus%, dmaterminal%   'Loop until terminal count bit set in DMA status register
'DMA Transfer is Now Complete
'Acknowledge the DSP interrupt by reading the DATA AVAILABLE port once
dummy% = INP(BlasterAddr% + &HE)    'DSP Available address
END SUB

DEFSNG A-Z
SUB playwav (wavefile$)


repeats% = 1
BlasterAddr% = GetBlasterAddr%
SELECT CASE BlasterAddr%
   CASE -2
      PRINT "Bad DMA Channel specified!"
      END
   CASE -1
      PRINT "No Port Base Address Given!"
      END
   CASE 0
      PRINT "No BLASTER Environment Variable Set!"
      END
   CASE ELSE
      'Assume a valid Address Exists
'      PRINT "Blaster Address = "; HEX$(BlasterAddr%)
END SELECT
IF NOT SBreset% THEN
   PRINT "SoundBlaster Card Would Not Reset!"
   END
END IF

sp% = INSTR(Spec$, " ")
IF sp% THEN
   wavefile$ = LEFT$(Spec$, sp% - 1)
   repeats% = VAL(RIGHT$(Spec$, LEN(Spec$) - sp%))
   IF repeats% = 0 THEN repeats% = 1
ELSE
   IF LEN(Spec$) THEN
      wavefile$ = Spec$
      repeats% = 1
   END IF
END IF

IF LEN(wavefile$) = 0 THEN
END IF
'wavefile$ = "C:\QBASIC\THEME.WAV"
CALL ValidWavHeader(wavefile$, LenHeader%, WavLen&, Channels%, Sampling&, bytes&, ok%)

IF NOT ok% THEN
   PRINT "Bad Wave File Format"
   END
END IF

MaxBuffer% = 7053

CALL WriteToDSP(&HD1)  'Speaker ON
FOR repeat% = 1 TO repeats%    'This can loop to play the file ii% times]
filenum% = FREEFILE
   OPEN wavefile$ FOR BINARY AS filenum%
      NUM% = 0
      SEEK filenum%, LenHeader% + 1
      Remaining& = WavLen&
      DO
         NUM% = NUM% + 1
         IF Remaining& > MaxBuffer% THEN
            BufferLen% = MaxBuffer%
         ELSE
            BufferLen% = Remaining&
         END IF
         Remaining& = Remaining& - BufferLen%
         buffer$ = SPACE$(BufferLen%)
         GET filenum%, , buffer$
         CALL PlayBack(buffer$, BufferLen%, Sampling&, bytes&, Channels%, NUM%)
      LOOP WHILE Remaining& > 0
      OUT &H20, &H20   'Reset Normal Interrupt Service
   CLOSE filenum%
NEXT repeat%
'CALL WriteToDSP(&HD3)  'Speaker OFF

END SUB

DEFINT A-Z
'------------------------------------------------------------------------------
FUNCTION SBreset%
'DSPreset% = address% + &H6
'DSPread% = address% + &HA
'DSPwrite% = address% + &HC
'DSPavail% = address% + &HE
'DSPmixer% = address% + &H4
OUT BlasterAddr% + &H6, 1   'Reset address
delay .1
OUT BlasterAddr% + &H6, 0
time1! = TIMER: noreset% = 0
DO
   'Read Data Available port until bit 7 is set
   'This should take about 100 micro seconds...give it 1 full second
   IF TIMER - time1! > 1! THEN noreset% = -1
LOOP UNTIL ((INP(BlasterAddr% + &HE) AND 128) = 128) OR noreset%
IF NOT noreset% THEN
   IF INP(BlasterAddr% + &HA) = &HAA THEN
      SBreset% = -1
   ELSE
      SBreset% = 0
   END IF
ELSE
   SBreset% = 0
END IF
END FUNCTION

' version 1.2
' up dates to this program are frequently made
' don't hesatae to get your latest version
' contact me at << swg3681@ircc.net>>
' i will be pleased to send you the latest version
' please specify your version in case it may be the current one
' if you make an improvement to this code and want it to be known
' don't hesatate to submit it to me at the above e-mail
'   @@@@@@@@
' speech macro written by Scott W Gates
' all the below string expressings apply just to examining the text at character & ASCII Level
' such as Chr(32) 'Spacebar'
' Reader is the reader status 1 if on 0 if off 'when speech is taking place
' lsize is the character size of the phrase len(phr$)
' Lc is used to count through the phrase to pick out the word$ (words)
'   using a Chr$(32) 'space' as a seperator
' Letr$ is used to assmeble word$
' Phr$ = the complete phrase typed in
' wc = the cuurent character being examined
' rword$ is the word being read without Chr$(32)
' moc moves the wc character marker :0 = inactive(idle) >0 will sum moc with wc
' word$ is the word with safety chr$(32) put in for nltr$ and pltr$ to work
' ltr$ return the current character being read
' Ltva is the number value of ltr$ hence Ltva = val(ltr$)
' nltr$ returns the next letter following the current wc position
' Nlltr$ returns the next to last letter (call) would give l
' Nltv returns the number value of the next character
' pltr$ returns the previous letter befor the current wc position
' Pltv returns the number value of the previous character
' wc is the marker indicating the current character being read
' lsize is the size of the phrase including chr$(32) or spaces
' rword$ is just the word being read no chr$(32) 'spaces
' rsword is len(rword$)
' ntv 'checks if current letter mid(word$,wc,1) is next to a vowel 'a,e,i,o,u'
' lv means long vowel 1 if true 0 if false
' cfv mean check for vowel 1 if true 0 if false :note this may not be directly of use to you
' wpb is the begging of the word len wize in phr$
' wpl is the words length wpl = len(word$) 'note its value is put in
' ch$ returns the character to be added when assembling  word$
' Pronum$ returns the condition of proper number pronunceation from
' Dormant if off
' Active if on
' vowels returns the number of vowels in word
'
SUB SPEAK (phr$)

 IF phr$ = "" THEN phr$ = "."

 RWORD$ = ""
 phr$ = phr$ + " "
 phr$ = LCASE$(phr$)
 reader = 0: wpb = 1: wpl = 1
'Get phrase size and check all letters
   lsize = LEN(phr$)

   FOR lc = 1 TO lsize
   letr$ = MID$(phr$, lc, 1)
   IF letr$ = CHR$(32) OR lc = (lsize) THEN word$ = MID$(phr$, wpb, wpl): reader = 1
    RWORD$ = ""
    FOR chc = 1 TO LEN(word$): CH$ = MID$(word$, chc, 1): IF CH$ <> CHR$(32) THEN RWORD$ = RWORD$ + CH$
    NEXT chc
  
      wpl = wpl + 1 ' needed to prevent contiuous loop
' show Reader status in
'   IF reader = 0 THEN PRINT "Idle"

'   IF reader = 1 THEN PRINT "Reading"
WHILE reader = 1
    IF wpl > 2 THEN lltr$ = MID$(RWORD$, wpl - 2, 1)
   IF wpl > 2 THEN nlltr$ = MID$(RWORD$, wpl - 2, 1):

   word$ = word$ + " ": word$ = " " + word$
   ' Show the word being read in cell "e:6"

   FOR wc = 2 TO wpl + 1 ' Read entire word compinsating for character placement
   IF wpl > 2 THEN pltr$ = MID$(word$, wc - 1, 1)
   LTR$ = MID$(word$, wc, 1): nltr$ = MID$(word$, wc + 1, 1)
   ltva = VAL(LTR$)
' sgl stands for single letter
' the below 'if then' statement test to see if the word is a single letter
' sgl returns a 1 if true 0 if false
   pltv = VAL(pltr$): nltv = VAL(nltr$) ' get the number values of the character if present
   IF pltr$ = CHR$(32) AND nltr$ = CHR$(32) THEN sgl = 1 ELSE sgl = 0
   IF wpl - wc >= 3 THEN L3tr$ = MID$(word$, wc + 2, 1)
' show l3tr$ in cell ("b:3")


' below section of this macro accesses the speech fragments
' it is concerned with assembling speech for numbers
' and commonly used words under united states English
   lv = 0
  'check to see if word has long vowels "a,e,i,o,u"
   IF LTR$ = "a" OR LTR$ = "e" OR LTR$ = "i" OR LTR$ = "o" OR LTR$ = "u" OR LTR$ = "y" THEN cfv = 1: vowels = vowels + 1
    IF cfv = 1 THEN IF nltr$ = "a" OR nltr$ = "e" OR nltr$ = "i" OR nltr$ = "o" OR nltr$ = "u" THEN lv = 1: ntv = 1: moc = 1
     IF cfv = 1 THEN IF lltr$ = "a" OR lltr$ = "e" OR lltr$ = "i" OR lltr$ = "o" OR lltr$ = "u" OR lltr$ = "y" THEN lv = 1
      IF cfv = 1 AND wc < wpl - 3 THEN IF LTR$ <> "o" AND nlltr$ = "a" OR nlltr$ = "e" OR nlltr$ = "i" OR nlltr$ = "o" OR nlltr$ = "u" THEN lv = 1
       'return check for vowel to zero hence cfv=0
        'cfv =1 if true 0 if false


   cfv = 0
   IF rsword = 1 THEN LTR$ = RWORD$

   '         [[[[[[[[   ]]]]]]]]
   ' [[[[[[[[  standard letters ]]]]]]]
   '         [[[[[[[[   ]]]]]]]]

' PRINT ltr$ 'for testing purposes only

'scope of "a"

   IF LTR$ = "a" AND sgl = 1 THEN SAY$ = "a": LTR$ = ""
 
    ' a cont aeiou section
' Scope of "b"
   IF LTR$ = "b" AND sgl = 1 THEN SAY$ = "b"
      IF LTR$ = "b" AND sgl = 0 THEN SAY$ = "bb"
'scope of "c"
IF LTR$ = "c" AND RWORD$ = "nice" THEN SAY$ = "ss": LTR$ = ""
 IF LTR$ = "c" AND RWORD$ = "space" THEN SAY$ = "ss": LTR$ = ""
  IF LTR$ = "c" AND RWORD$ = "come" THEN SAY$ = "kk": LTR$ = ""
   IF LTR$ = "c" AND sgl = 1 THEN SAY$ = "c": LTR$ = ""
    IF LTR$ = "c" AND nltr$ = "h" THEN SAY$ = "ch": LTR$ = "": moc = 1' ch as in church
     IF LTR$ = "c" AND nltr$ = "k" THEN moc = 1: SAY$ = "kk": LTR$ = ""
      IF LTR$ = "c" AND RWORD$ = "cell" THEN SAY$ = "ss": LTR$ = ""
       IF LTR$ = "c" AND ntv = 1 THEN SAY$ = "ss": LTR$ = ""
        IF LTR$ = "c" AND sgl = 0 AND ntv = 0 THEN SAY$ = "Cc": LTR$ = ""
         IF LTR$ = "c" AND ntv = 1 THEN SAY$ = "kk": LTR$ = ""
          IF LTR$ = "c" AND sgl = 0 AND L3tr$ <> "t" THEN SAY$ = "ss": LTR$ = ""
           IF LTR$ = "c" AND nltr$ = "c" THEN moc = 1: SAY$ = "kk"
' scope of "d"
   IF LTR$ = "d" AND sgl = 1 THEN SAY$ = "d"
     IF LTR$ = "d" AND sgl = 0 THEN SAY$ = "dd"
' scope of "e"
   IF LTR$ = "e" AND sgl = 1 THEN SAY$ = "e": LTR$ = ""
     ' e phonix at aeiou section
' scope of "f"
   IF LTR$ = "f" AND sgl = 1 THEN SAY$ = "f"
      IF LTR$ = "f" AND sgl = 0 THEN SAY$ = "ff"
' scope of "g"
  'PRINT ltr$
 IF LTR$ = "g" AND RWORD$ = "sign" THEN SAY$ = "": LTR$ = ""
  IF LTR$ = "g" AND pltr$ = "e" THEN SAY$ = "gg": LTR$ = ""
   IF LTR$ = "g" AND nltr$ = "r" THEN SAY$ = "gg": LTR$ = ""
    IF LTR$ = "g" AND pltr$ <> CHR$(32) AND nltr$ <> CHR$(32) THEN SAY$ = "JJ": LTR$ = ""
     IF LTR$ = "g" AND sgl = 1 THEN SAY$ = "g"
      IF LTR$ = "g" AND sgl = 0 THEN SAY$ = "gg"
' scope of "h"
   IF LTR$ = "h" AND sgl = 1 THEN SAY$ = "h"
      IF LTR$ = "h" AND sgl = 0 THEN SAY$ = "hh" 'h as in horse
' scope of "i"
   IF LTR$ = "i" AND sgl = 1 THEN SAY$ = "i": LTR$ = ""
' scope of "j"
   IF LTR$ = "j" AND sgl = 1 THEN SAY$ = "j"
      IF LTR$ = "j" AND sgl = 0 THEN SAY$ = "jj"
' scope of "k"
   IF LTR$ = "k" AND sgl = 1 THEN SAY$ = "k"
      IF LTR$ = "k" AND sgl = 0 THEN SAY$ = "kk"
' scope of "l"
   IF LTR$ = "l" AND sgl = 1 THEN SAY$ = "l"
      IF LTR$ = "l" AND sgl = 0 THEN SAY$ = "ll": REM  If nltr$ = "l" Then moc = 2
' scope of "m"
   IF LTR$ = "m" AND sgl = 1 THEN SAY$ = "m"
      IF LTR$ = "m" AND agl = 0 THEN SAY$ = "mm" ' m as in mouse
' scope of "n"
   IF LTR$ = "n" AND sgl = 1 THEN SAY$ = "n"
      IF LTR$ = "n" AND sgl = 0 THEN SAY$ = "nn"
' scope of "o"
   IF LTR$ = "o" AND sgl = 1 THEN SAY$ = "o"
      ' o's phonixe cont at aeiou section
' scope of "p"
   IF LTR$ = "p" AND sgl = 1 THEN SAY$ = "p"
      IF LTR$ = "p" AND sgl = 0 THEN SAY$ = "pp"
' scope of "q"
   IF LTR$ = "q" AND sgl = 1 THEN SAY$ = "q"
      IF LTR$ = "q" AND sgl = 0 THEN SAY$ = "k"
' scope of "r"
   IF LTR$ = "r" AND sgl = 1 THEN SAY$ = "r"
      IF LTR$ = "r" AND sgl = 0 THEN SAY$ = "rr"
       IF LTR$ = "r" AND nltr$ = "r" THEN moc = 1
' scope of "s"

   IF LTR$ = "s" AND sgl = 1 THEN SAY$ = "s"
     IF LTR$ = "s" AND nltr$ = "h" THEN SAY$ = "sh": moc = 1: LTR$ = "" ' sh as in shack
      IF LTR$ = "s" AND sgl = 0 THEN SAY$ = "ss"

' scope of "t"
   IF LTR$ = "t" AND sgl = 1 THEN SAY$ = "t"
    ' "th" as in the
     IF LTR$ = "t" AND nltr$ = "h" THEN moc = 1: SAY$ = "th": LTR$ = ""' rem th
      IF LTR$ = "t" AND sgl = 0 THEN SAY$ = "tt"
       IF LTR$ = "t" AND nltr$ = "t" THEN moc = 1: LTR$ = ""
  
' scope of "u"
   IF LTR$ = "u" AND sgl = 1 THEN SAY$ = "u": LTR$ = ""
' scope of "v"
   IF LTR$ = "v" AND sgl = 1 THEN SAY$ = "v"
      IF LTR$ = "v" AND sgl = 0 THEN SAY$ = "vv"
' scope of "w"
   IF LTR$ = "w" AND sgl = 1 THEN SAY$ = "w"
      IF LTR$ = "w" AND sgl = 0 THEN SAY$ = "ww"
' scope of "x"
   IF LTR$ = "x" THEN SAY$ = "x"
' scope of "y"
IF RWORD$ = "my" AND LTR$ = "y" THEN SAY$ = "i": LTR$ = ""
 IF LTR$ = "y" AND RWORD$ = "by" THEN SAY$ = "i": LTR$ = ""
  IF LTR$ = "y" AND nltr$ = "" THEN SAY$ = "e": LTR$ = ""
   IF LTR$ = "y" AND nltr$ = "e" THEN SAY$ = "yy": LTR$ = ""
    IF LTR$ = "y" AND RWORD$ = "you" THEN SAY$ = "U": LTR$ = "": wc = lsize: word$ = ""
     IF LTR$ = "y" AND nltr$ = "o" THEN SAY$ = "yy": LTR$ = ""
      IF LTR$ = "y" AND pltr$ = "n" THEN SAY$ = "E": LTR$ = ""
       IF LTR$ = "y" AND RWORD$ = "byte" THEN SAY$ = "i": LTR$ = ""
        IF LTR$ = "y" AND sgl = 0 AND lv = 0 THEN SAY$ = "yy": LTR$ = ""
         IF LTR$ = "y" AND sgl = 1 THEN SAY$ = "y"
          IF LTR$ = "y" AND pltr$ <> CHR$(32) THEN SAY$ = "e"
           IF LTR$ = "y" AND nltr$ = CHR$(32) THEN SAY$ = "e": LTR$ = ""

' scope of "z"
   IF LTR$ = "z" AND sgl = 1 THEN SAY$ = "z"
      IF LTR$ = "z" AND sgl = 0 THEN SAY$ = "zz"
' end of standard letters

' special phonix section 'a,e,i,o,u'
' vowel "a"
  IF LTR$ = "a" AND RWORD$ = "gates" THEN SAY$ = "a": LTR$ = ""
   IF LTR$ = "a" AND RWORD$ = "have" THEN SAY$ = "AA": LTR$ = ""
    IF LTR$ = "a" AND RWORD$ = "start" THEN SAY$ = "R": LTR$ = ""
     IF LTR$ = "a" AND RWORD$ = "are" THEN SAY$ = "r": LTR$ = "": word$ = "" 'force "R" for "are"
      IF LTR$ = "a" AND RWORD$ = "happy" THEN SAY$ = "aa": LTR$ = ""
       IF LTR$ = "a" AND lv = 1 AND nltr$ <> "r" THEN SAY$ = "a": LTR$ = ""
        IF LTR$ = "a" AND nltr$ = "r" AND lv = 1 THEN SAY$ = "r": LTR$ = "": moc = 1
         IF LTR$ = "a" AND lv = 0 THEN SAY$ = "aa": LTR$ = ""
          IF LTR$ = "a" AND lltr$ = "e" THEN SAY$ = "a": LTR$ = ""
           IF LTR$ = "a" AND sgl = 0 AND lltr$ <> "e" THEN SAY$ = "a": LTR$ = ""
            IF LTR$ = "a" AND lv = 0 THEN SAY$ = "aa": LTR$ = ""



' vowel "e
IF LTR$ = "e" AND RWORD$ = "the" THEN SAY$ = "e": LTR$ = ""
 IF LTR$ = "e" AND RWORD$ = "zero" THEN SAY$ = "e": LTR$ = ""
  IF LTR$ = "e" AND RWORD$ = "error" THEN SAY$ = "a": LTR$ = ""
   IF LTR$ = "e" AND nltr$ = CHR$(32) AND lv = 1 THEN SAY$ = "": LTR$ = ""
    IF LTR$ = "e" AND nltr$ = CHR$(32) THEN SAY$ = "e": LTR$ = ""
     IF LTR$ = "e" AND nltr$ = "r" THEN SAY$ = "": LTR$ = ""
      IF LTR$ = "e" AND lltr$ = "y" THEN SAY$ = "EE": LTR$ = ""
       IF LTR$ = "e" AND ntv = 0 AND nltr$ <> CHR$(32) THEN SAY$ = "ee": LTR$ = ""
        IF LTR$ = "e" AND nltr$ = "n" THEN SAY$ = "ii": LTR$ = ""
         IF LTR$ = "e" AND RWORD$ = "welcome" AND pltr$ = "w" THEN SAY$ = "ee": LTR$ = ""
          IF LTR$ = "e" AND RWORD$ = "byte" THEN SAY$ = "": LTR$ = ""
           IF LTR$ = "e" AND RWORD$ = "here" AND pltr$ <> "r" THEN SAY$ = "e"
            IF LTR$ = "e" AND RWORD$ = "come" THEN SAY$ = "": LTR$ = ""
             IF LTR$ = "e" AND RWORD$ = "there" THEN SAY$ = "eee": LTR$ = ""
              IF LTR$ = "e" AND RWORD$ = "the" THEN SAY$ = "e": LTR$ = "":    ' force long e for "the"
               IF LTR$ = "e" AND nltr$ = "r" THEN SAY$ = "e": LTR$ = ""
                IF LTR$ = "e" AND wc < wpl AND pltr$ <> "p" AND lltr$ <> "o" AND lv = 1 THEN SAY$ = "e":  LTR$ = ""
                 IF LTR$ = "e" AND lv = 1 AND ntv = 1 AND wc < wpl AND pltr$ <> "P" AND lltr$ <> "o" THEN SAY$ = "e": LTR$ = ""
                  IF LTR$ = "e" AND lv = 1 AND sgl = 0 AND pltr$ <> "p" AND wc < wpl THEN SAY$ = "ee": LTR$ = ""
                   IF LTR$ = "e" AND lv = 0 THEN SAY$ = "e": LTR$ = ""
                    IF LTR$ = "e" AND lv = 1 THEN SAY$ = "e": LTR$ = ""
                     
                       'when all else fails long "e"




  ' vowel "i"
 IF LTR$ = "i" AND RWORD$ = "sign" THEN SAY$ = "i": LTR$ = ""
  IF LTR$ = "i" AND RWORD$ = "hi" THEN SAY$ = "i": LTR$ = "" ' force long i as in "hi"
   IF LTR$ = "i" AND ntv = 0 AND lv = 0 THEN SAY$ = "ii": LTR$ = ""
      IF LTR$ = "i" AND lv = 1 THEN SAY$ = "i": LTR$ = ""

' vowel "o"

 IF LTR$ = "o" AND RWORD$ = "do" THEN SAY$ = "oo": LTR$ = ""
  IF LTR$ = "o" AND nltr$ = "u" AND lltr$ <> "d" THEN SAY$ = "oo": moc = 1: LTR$ = ""
   IF LTR$ = "o" AND nltr$ = "u" THEN SAY$ = "aa": LTR$ = ""
    ' "OU" AS IN FOUND OR SOUND = FORCES AA.WAV
     IF LTR$ = "o" AND pltr$ = "c" AND lv = 0 THEN SAY$ = "aaa": LTR$ = ""
      IF LTR$ = "o" AND nltr$ = "m" THEN SAY$ = "uu": LTR$ = ""
       IF LTR$ = "o" AND RWORD$ = "come" THEN SAY$ = "o"
        IF LTR$ = "o" AND RWORD$ = "tron" THEN SAY$ = "aaa": LTR$ = ""
         IF LTR$ = "o" AND nltr$ = "w" THEN SAY$ = "aaa": LTR$ = ""
          IF LTR$ = "o" AND plltr$ = "z" THEN SAY$ = "o": LTR$ = ""
           IF LTR$ = "o" AND nltr$ = "o" THEN SAY$ = "oo": LTR$ = ""
            IF LTR$ = "o" AND pltr$ = "t" THEN SAY$ = "oo": LTR$ = ""
             IF LTR$ = "o" AND nltr$ = CHR$(32) AND lv = 1 THEN SAY$ = "o": LTR$ = ""
              ' o as in 'on'
               IF LTR$ = "o" AND pltr$ = CHR$(32) THEN SAY$ = "aaa": LTR$ = ""
                IF LTR$ = "o" AND lv = 1 AND nltr$ <> "o" AND ntv = 1 THEN SAY$ = "o": LTR$ = ""
                 IF LTR$ = "o" THEN SAY$ = "o"
' vowel "u"
 IF LTR$ = "u" AND RWORD$ = "stupid" THEN SAY$ = "oo": LTR$ = ""
  IF LTR$ = "u" AND RWORD$ = "user" THEN SAY$ = "u": LTR$ = ""
   IF LTR$ = "u" AND lv = 0 THEN SAY$ = "uu"
     IF LTR$ = "u" AND lv = 1 THEN SAY$ = "oo": 'leave open for next test of "u"
   
   
   
   
   
   
'   end of vowel section
   
     IF moc > 0 THEN wc = wc + moc: moc = 0
     IF wc > wpl THEN word$ = ""
   lv = 0
' end of special vowel "a,e,i,o,u" section
' Numbers this should be self explanatory...

IF LTR$ = "0" THEN SPEAK ("zero")
IF LTR$ = "9" THEN SPEAK ("nine")
IF LTR$ = "8" THEN SPEAK ("ate")
IF LTR$ = "7" THEN SPEAK ("seven")
IF LTR$ = "6" THEN SPEAK ("six")
IF LTR$ = "5" THEN SPEAK ("five")
IF LTR$ = "4" THEN SPEAK ("for")
IF LTR$ = "3" THEN SPEAK ("three")
IF LTR$ = "2" THEN SPEAK ("to")
IF LTR$ = "1" THEN SPEAK ("wun")
' end of numbers
  IF wc >= wpl THEN reader = 0: LTR$ = "": RWORD$ = ""
  IF wpl = 1 THEN word$ = "": RWORD$ = "": LTR$ = ""

  LTR$ = ""
 IF SAY$ <> "" THEN playwav "c:\windows\sound\qbspeech\" + SAY$ + ".wav"

'  PRINT say$
  SAY$ = ""
NEXT wc

 nlltr$ = "": wpl = 1: wpb = lc: ntv = 0: vowels = 0: lv = 0: L3tr$ = ""
 WEND
  NEXT lc






 END SUB

'------------------------------------------------------------------------------
SUB ValidWavHeader (file$, LenHeader%, dataLen&, nChannels%, nSamplesPerSec&, nAvgBytesPerSec&, ok%)
rID$ = SPACE$(4)
wID$ = SPACE$(4)
fID$ = SPACE$(4)
dat$ = SPACE$(4)
dummy$ = SPACE$(1)

filenum% = FREEFILE
OPEN file$ FOR BINARY AS filenum%
  GET filenum%, , rID$
  GET filenum%, , rLen&
  GET filenum%, , wID$
  GET filenum%, , fID$
  GET filenum%, , fLen&
  GET filenum%, , wFormatTag%       '2 bytes
  GET filenum%, , nChannels%        '2 bytes
  GET filenum%, , nSamplesPerSec&   '4 bytes
  GET filenum%, , nAvgBytesPerSec&  '4 bytes
  GET filenum%, , nBlockAlign%      '2 bytes
  GET filenum%, , FormatSpecific%   '2 bytes
  'Read bytes until have read fLen& total bytes.
  'I have no idea what these next bytes are used for (if they even exist).
  FOR I% = 1 TO fLen& - 16          '16 bytes is what we have read in so far
     GET filenum%, , dummy$         'read in 1 byte at a time
  NEXT I%
  GET filenum%, , dat$
  IF UCASE$(dat$) = "FACT" THEN
     'funny format...
     GET filenum%, , dummy&
     GET filenum%, , dummy&
     GET filenum%, , dat$
  END IF
  GET filenum%, , dataLen&
  LenHeader% = LOC(1)
CLOSE filenum%
'  PRINT rID$;
'  PRINT rLen&;
'  PRINT wID$;
'  PRINT fID$;
'  PRINT fLen&;
'  PRINT wFormatTag%;       '2 bytes
'  PRINT nChannels%;        '2 bytes
'  PRINT nSamplesPerSec&;   '4 bytes
'  PRINT nAvgBytesPerSec&;  '4 bytes
'  PRINT nBlockAlign%;      '2 bytes
'  PRINT FormatSpecific%;   '2 bytes
'  PRINT dat$;
'  PRINT dataLen&;
'  PRINT LenHeader%
IF UCASE$(rID$) = "RIFF" THEN
   IF UCASE$(wID$) = "WAVE" THEN
      IF UCASE$(dat$) = "DATA" THEN
         IF UCASE$(fID$) = "FMT " THEN
           IF FormatSpecific% = 8 THEN ok% = -1
         END IF
      END IF
   END IF
END IF
END SUB

SUB verbal
LOCATE 23, 1: PRINT "         "
DO
        OUT CommAddr, &H20
        BYTE = INP(DataAddr)
    LOCATE 23, 1: PRINT BYTE
LOOP UNTIL BYTE <> 128

LOCATE 23, 1: PRINT "_________"

END SUB

'------------------------------------------------------------------------------
SUB WriteToDSP (v%)
DO
LOOP UNTIL (INP(BlasterAddr% + &HC) AND 128) = 0
OUT BlasterAddr% + &HC, v%
END SUB

SUB ZEROMIC

DO              'delay MIC INPUT TO GET RID OF SPIKE
OUT CommAddr, &H20
BYTE = INP(DataAddr)
LOOP UNTIL BYTE = 128

END SUB

