



COMMON SHARED BlasterAddr%, dma%, repeats%


'speech phonix handling subs

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% ()

' the below declarations i didn't write


DECLARE SUB DrawCheckedBox (posi%)
DECLARE SUB SetListBoxFocus (posi%, prev%)
DECLARE SUB CheckListBox ()
DEFINT A-Z
DECLARE SUB fprint (Text$, textx%, texty%, colour%, file%)
DECLARE SUB fopen (file$, file%)
DECLARE SUB redraw ()

'Subs Used by Text Boxes
'-------------------------
DECLARE SUB DrawTextBox (position%)
DECLARE SUB mTextBox (nam, x, y, lenght, label$)
DECLARE SUB PutCharOnBox (letter$)
DECLARE SUB PrintLabel (TextBoxNum, clr)

'Subs Used by Buttons
'-------------------------
DECLARE SUB DrawButton (position)
DECLARE SUB mButton (nam, x, y, lenght, label$)
DECLARE SUB PrintButtonLabel (ButtonNum, clr)
DECLARE SUB DrawButtonDown (position)

'Subs Used by List Boxes
'-------------------------
DECLARE SUB DrawListBox (position)
DECLARE SUB mListBox (nam, x, y, xlen, ylen, label$)
DECLARE SUB UpdateListBox (position, top, way)



DECLARE SUB SetNewFocus ()
DECLARE SUB PlayWarning ()

'=============== MOUSE STUFF ==============

DECLARE SUB mouse (which)
DIM SHARED mouser$, MouseLeftButton, MouseRightButton, mousexpos, mouseypos, AX%, bx%, cx%, dx%
mouse 0

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

' ==========================================






TYPE TypeTextBox
 nam AS INTEGER
 x AS INTEGER
 y AS INTEGER
 lenght AS INTEGER
 label AS STRING * 20
 maxtext AS INTEGER
 readtext AS STRING * 100
END TYPE

TYPE TypeButton
 nam AS INTEGER
 x AS INTEGER
 y AS INTEGER
 lenght AS INTEGER
END TYPE

TYPE TypeListBox
 nam AS INTEGER
 x AS INTEGER
 xlen AS INTEGER
 y AS INTEGER
 ylen AS INTEGER
 show AS INTEGER
 top AS INTEGER
 selected AS INTEGER
 NumItems AS INTEGER
 scrollspeed AS INTEGER         'Bigger the slower
 speedcounter AS INTEGER
 redraw AS INTEGER
END TYPE

DIM SHARED ObjectFocus

DIM SHARED MaxTextBoxes, ActiveTextBoxes, TextBoxFocus
MaxTextBoxes = 10
DIM SHARED TextBoxResult$(MaxTextBoxes)
DIM SHARED TextBox(MaxTextBoxes) AS TypeTextBox


DIM SHARED MaxButtons, ActiveButtons, ButtonFocus
MaxButtons = 10
DIM SHARED Button(MaxButtons) AS TypeButton, ButtonLabel$(MaxButtons)

DIM SHARED MaxListBoxes, MaxListItems, ActiveListBoxes, ListBoxFocus, ListBoxScrollingSpeed
MaxListBoxes = 5
MaxListItems = 20
ListBoxScrollingSpeed = 300    'The Bigger the Slower the List Boxes will scroll,
                               'the smaller, well, like a flash.
DIM SHARED ListBox(MaxListBoxes) AS TypeListBox, ListBoxContent$(MaxListBoxes, MaxListItems), ListBoxLabel$(MaxListBoxes), SelectedLine(MaxListBoxes)



SCREEN 12
COLOR 1
PAINT (1, 1), 9, 9

speak ("hi")

10 PRINT mousexpos, mouseypos
mouse (3)





ke$ = INKEY$
IF ke$ = "s" THEN speak ("hi")
IF ke$ = "t" THEN speak ("yes")



2000 GOTO 10

SUB CheckListBox

FOR xx = 1 TO ActiveListBoxes
 x = ListBox(xx).x + 2
 y = ListBox(xx).y + 3
 xlen = x + ListBox(xx).xlen - 2
 ylen = y + ListBox(xx).ylen - 2


 x1 = ListBox(xx).x + ListBox(xx).xlen
 y1 = ListBox(xx).y
 Xmax1 = x1 + 10
 Ymax1 = y1 + 15

 x2 = ListBox(xx).x + ListBox(xx).xlen
 y2 = ListBox(xx).y + ListBox(xx).ylen
 Xmax2 = ListBox(xx).x + x2
 Ymax2 = ListBox(xx).y + ListBox(xx).ylen - 15

 top = ListBox(xx).top
 scrollspeed = ListBox(xx).scrollspeed


 IF (mousexpos >= x1) AND (mousexpos <= Xmax1) AND (mouseypos >= y1) AND (mouseypos <= y2) THEN
  IF (mousexpos >= x1) AND (mousexpos <= Xmax1) AND (mouseypos >= y1) AND (mouseypos <= Ymax1) THEN
   IF ListBox(xx).speedcounter = scrollspeed THEN
    ListBox(xx).speedcounter = 0
    UpdateListBox xx, top, 1
    
    EXIT FOR
   ELSE
    ListBox(xx).speedcounter = ListBox(xx).speedcounter + 1
   END IF
  ELSE
   IF (mousexpos >= x2) AND (mousexpos <= Xmax2) AND (mouseypos <= y2) AND (mouseypos >= Ymax2) THEN
    IF ListBox(xx).speedcounter = scrollspeed THEN
     ListBox(xx).speedcounter = 0
     UpdateListBox xx, top, 0
    ELSE
     ListBox(xx).speedcounter = ListBox(xx).speedcounter + 1
    END IF
    EXIT SUB
   END IF
  END IF
 ELSE
  IF (mousexpos >= x) AND (mousexpos <= xlen) AND (mouseypos >= y) AND (mouseypos <= ylen) THEN
   IF ListBox(xx).speedcounter = scrollspeed THEN
    yposition = (mouseypos - y)
    prev = ListBox(xx).selected
    ListBox(xx).selected = INT(yposition \ 10) + 1
    ListBox(xx).redraw = 1
    SetListBoxFocus xx, prev
   ELSE
    ListBox(xx).speedcounter = ListBox(xx).speedcounter + 1
   END IF
  END IF
 END IF
NEXT xx




END SUB

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

SUB DrawButton (posi)

x = Button(posi).x
y = Button(posi).y
lenght = Button(posi).lenght
Text$ = ButtonLabel$(posi)

LINE (x, y)-(x + lenght, y + 17), 9, BF
LINE (x, y)-(x + lenght, y + 17), 0, B
PAINT (x + 1, y + 1), 7, 0

LINE (x, y)-(x + lenght - 1, y), 15
LINE (x, y)-(x, y + 16), 15

lenght = INT(lenght / 2)
Middle = INT(((LEN(Text$))) * 6.7)
Middle = INT(Middle / 2)
position = lenght - Middle


fprint Text$, x + position, y + 3, 0, 2

END SUB

SUB DrawButtonDown (position)

posi = position
x = Button(posi).x
y = Button(posi).y
lenght = Button(posi).lenght
Text$ = ButtonLabel$(posi)

LINE (x, y)-(x + lenght, y + 17), 9, BF
LINE (x, y)-(x + lenght - 1, y + 16), 0, B
PAINT (x + 2, y + 2), 7, 0

lenght = INT(lenght / 2)
Middle = INT(((LEN(Text$))) * 6.7)
Middle = INT(Middle / 2)
Positionn = lenght - Middle


fprint Text$, x + Positionn + 2, y + 4, 0, 2




END SUB

SUB DrawListBox (posi)


x = ListBox(posi).x
y = ListBox(posi).y
xlen = ListBox(posi).xlen
ylen = ListBox(posi).ylen
Text$ = ListBoxLabel$(posi)
NumItems = ListBox(posi).NumItems
show = ListBox(posi).show
selected = ListBox(posi).selected
top = ListBox(posi).top


LINE (x, y)-(x + xlen, y + ylen), 0, B
LINE (x + 1, y + 1)-(x + xlen - 1, y + ylen - 1), 0, B

PAINT (x + 2, y + 2), 15, 0
LINE (x, y + ylen)-(x + xlen, y + ylen), 7
LINE (x + 1, y + ylen - 1)-(x + xlen, y + ylen - 1), 7

LINE (x + xlen, y)-(x + xlen, y + ylen), 7
LINE (x + xlen - 1, y + 1)-(x + xlen - 1, y + ylen), 7



fprint Text$, x + 2, y - 10, 0, 2


'Draw Arrow Buttons and Stuff
LINE (x + xlen + 1, y)-(x + xlen + 13, y + ylen), 8, BF

LINE (x + xlen + 5, y + 10)-(x + xlen + 8, y + 15), 7, BF
LINE (x + xlen + 2, y + 10)-(x + xlen + 7, y + 5), 7
LINE (x + xlen + 12, y + 10)-(x + xlen + 7, y + 5), 7
LINE (x + xlen + 2, y + 10)-(x + xlen + 12, y + 10), 7

PAINT (x + xlen + 7, y + 7), 7, 7


LINE (x + xlen + 5, y + (ylen - 10))-(x + xlen + 8, y + (ylen - 15)), 7, BF
LINE (x + xlen + 2, y + (ylen - 10))-(x + xlen + 7, y + (ylen - 5)), 7
LINE (x + xlen + 12, y + (ylen - 10))-(x + xlen + 7, y + (ylen - 5)), 7
LINE (x + xlen + 2, y + (ylen - 10))-(x + xlen + 12, y + (ylen - 10)), 7

PAINT (x + xlen + 7, y + (ylen - 7)), 7, 7




'Print Items On List Box

row = y
row = row + 3
IF top = 1 THEN
 FOR ss = 1 TO NumItems
  fprint ListBoxContent$(posi, ss), x + 5, row, 0, 2
  row = row + 10
  IF show = ss THEN EXIT FOR
 NEXT ss
ELSE
 
 FOR ss = top TO NumItems
  fprint ListBoxContent$(posi, ss), x + 5, row, 0, 2
  row = row + 10
  IF show = ss THEN EXIT FOR
 NEXT ss
END IF



END SUB

SUB DrawTextBox (position)


x = TextBox(position).x
y = TextBox(position).y
lenght = TextBox(position).lenght
Text$ = TextBox(position).label



LINE (x, y)-(x + lenght, y + 17), 8, B
LINE (x + 1, y + 1)-(x + lenght - 1, y + 16), 8, B
PAINT (x + 2, y + 2), 15, 8

LINE (x + 1, y + 16)-(x + lenght - 1, y + 16), 7
LINE (x, y + 17)-(x + lenght, y + 17), 7

LINE (x + lenght - 1, y + 1)-(x + lenght - 1, y + 16), 7
LINE (x + lenght, y)-(x + lenght, y + 17), 7


PrintLabel position, 0





END SUB

SUB fopen (file$, file%)

  OPEN file$ FOR RANDOM AS file% LEN = 2
  'Just to make it easier for those of you who dont
  'understand the OPEN command yet! ;)

END SUB

SUB fprint (Text$, textx%, texty%, colour%, file%)

  'lpi: lines per integer
  'fws: font word spacing
  'fls: font letter spacing
  'p% : pointer
  GET file%, 1, lpi%
  GET file%, 2, fws%
  GET file%, 3, fls%
  FOR count% = 1 TO LEN(Text$)
    m% = ASC(MID$(Text$, count%, 1)) - 29
    IF m% > 3 THEN
      GET file%, m%, a1%
      GET file%, m% + 1, a2%
      FOR n% = a1% TO a2% - 1 STEP lpi%
        FOR z% = 0 TO lpi% - 1
          GET file%, n% + z%, L%
           LINE (p% + textx%, (16 * z%) + texty%)-(p% + textx%, (16 * z%) + 15 + texty%), colour%, , L%
        NEXT z%
        p% = p% + 1
      NEXT n%
      p% = p% + fls%
    ELSE
      p% = p% + fws%
    END IF
  NEXT count%





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

SUB mButton (nam, x, y, lenght, label$)

pointer = 1
DO
 IF Button(pointer).nam <> 0 THEN
  pointer = pointer + 1
 END IF
LOOP UNTIL Button(pointer).nam = 0

ActiveButtons = ActiveButtons + 1
Button(pointer).nam = nam
Button(pointer).x = x
Button(pointer).y = y
Button(pointer).lenght = lenght
ButtonLabel$(pointer) = label$
DrawButton pointer



END SUB

SUB mListBox (nam, x, y, xlen, ylen, label$)


pointer = 1
DO
 IF ListBox(pointer).nam <> 0 THEN
  pointer = pointer + 1
 END IF
LOOP UNTIL ListBox(pointer).nam = 0

ActiveListBoxes = ActiveListBoxes + 1
ListBox(pointer).nam = nam
ListBox(pointer).x = x
ListBox(pointer).y = y
ListBox(pointer).xlen = xlen
ListBox(pointer).ylen = ylen
ListBox(pointer).show = (INT(ylen \ 10)) - 1
ListBox(pointer).top = 1
ListBox(pointer).scrollspeed = ListBoxScrollingSpeed
ListBox(pointer).speedcounter = 0
ListBoxLabel$(pointer) = label$
ListBox(pointer).redraw = 0
SelectedLine(pointer) = 1
DrawListBox pointer





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 mTextBox (nam, x, y, lenght, label$)

pointer = 1
DO
 IF TextBox(pointer).nam <> 0 THEN
  pointer = pointer + 1
 END IF
LOOP UNTIL TextBox(pointer).nam = 0

ActiveTextBoxes = ActiveTextBoxes + 1
TextBox(pointer).nam = nam
TextBox(pointer).x = x
TextBox(pointer).y = y
TextBox(pointer).lenght = lenght
TextBox(pointer).label = label$
TextBox(pointer).maxtext = INT(lenght / 8)
DrawTextBox pointer


END SUB

'------------------------------------------------------------------------------
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

SUB PlayWarning


SOUND 600, .05
SOUND 700, .05


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
SUB PrintButtonLabel (ButtonNum, clr)


x = Button(posi).x
y = Button(posi).y
lenght = Button(posi).lenght
Text$ = ButtonLabel$(posi)

lenght = INT(lenght / 2)
Middle = INT(((LEN(Text$))) * 6.7)
Middle = INT(Middle / 2)
position = lenght - Middle


fprint Text$, x + position, y + 3, clr, 2


END SUB

SUB PrintLabel (TextBoxNum, clr)

IF ActiveTextBoxes <> 0 THEN
 x = TextBoxNum
 Text$ = TextBox(x).label
 fprint Text$, TextBox(x).x + 2, TextBox(x).y - 10, clr, 2
END IF

END SUB

SUB PutCharOnBox (result$)

IF ActiveTextBoxes <> 0 THEN
 Text$ = TextBoxResult$(TextBoxFocus)
 L = LEN(Text$)


 IF CHR$(8) = result$ THEN
  IF L = 0 THEN
  ELSE
   fprint Text$, TextBox(TextBoxFocus).x + 4, TextBox(TextBoxFocus).y, 15, 1
   Text$ = LEFT$(Text$, L - 1)
   fprint Text$, TextBox(TextBoxFocus).x + 4, TextBox(TextBoxFocus).y, 0, 1
  END IF
 ELSE
  IF LEN(Text$) >= TextBox(TextBoxFocus).maxtext THEN
   PlayWarning
  ELSE
   Text$ = Text$ + result$
   TextBoxResult$(TextBoxFocus) = Text$
   fprint Text$, TextBox(TextBoxFocus).x + 4, TextBox(TextBoxFocus).y, 0, 1
  END IF
 END IF

 TextBoxResult$(TextBoxFocus) = Text$
END IF

END SUB

SUB redraw


FOR xx = 1 TO ActiveListBoxes
 x = ListBox(xx).x
 y = ListBox(xx).y
 x2 = x + ListBox(xx).xlen + 13
 y2 = y + ListBox(xx).ylen
 draww = ListBox(xx).redraw
 prev = ListBox(xx).selected

 IF draww = 1 THEN
  IF (mousexpos >= x2) OR (mousexpos <= x) OR (mouseypos >= y2) OR (mouseypos <= y) THEN
   ListBox(xx).redraw = 0
   DrawListBox xx
   SetListBoxFocus xx, prev
  END IF
 END IF
NEXT xx
END SUB

'------------------------------------------------------------------------------
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

SUB SetListBoxFocus (posi, prev)

row = ListBox(posi).y + 3
x = ListBox(posi).x
xlen = x + ListBox(posi).xlen
y = ListBox(posi).y
top = ListBox(posi).top
selected = ListBox(posi).selected
old$ = ListBoxContent$(posi, prev + top - 1)
new$ = ListBoxContent$(posi, selected + top - 1)
NumItems = ListBox(posi).NumItems
SelectedLine(posi) = (selected + top - 1)


IF prev = 1 THEN
 LINE (x + 2, row + 2)-(xlen - 2, row + 9), 15, BF
 fprint old$, x + 5, row, 0, 2
ELSE
 FOR ss = 1 TO NumItems
  IF ss = prev THEN
   LINE (x + 2, row + 2)-(xlen - 2, row + 9), 15, BF
   fprint old$, x + 5, row, 0, 2
  ELSE
   row = row + 10
  END IF
 NEXT ss
END IF


row = ListBox(posi).y + 3
IF selected = 1 THEN
 LINE (x + 2, row + 2)-(xlen - 2, row + 9), 1, BF
 fprint old$, x + 5, row, 15, 2
ELSE
 FOR ss = 1 TO NumItems
  IF ss = selected THEN
   LINE (x + 2, row + 2)-(xlen - 2, row + 9), 1, BF
   fprint old$, x + 5, row, 15, 2
  ELSE
   row = row + 10
  END IF
 NEXT ss
END IF





END SUB

SUB SetNewFocus



 IF MouseLeftButton = -1 THEN
  FOR xx = 1 TO ActiveTextBoxes
   IF (mousexpos >= TextBox(xx).x) AND (mousexpos <= TextBox(xx).x + TextBox(xx).lenght) AND (mouseypos >= TextBox(xx).y) AND (mouseypos <= TextBox(xx).y + 17) THEN
    PrintLabel TextBoxFocus, 0
    TextBoxFocus = xx
    PrintLabel TextBoxFocus, 15
   END IF
  NEXT xx
 ELSE
  IF TextBoxFocus = ActiveTextBoxes THEN
   PrintLabel TextBoxFocus, 0
   TextBoxFocus = 1
   PrintLabel TextBoxFocus, 15
  ELSE
   PrintLabel TextBoxFocus, 0
   TextBoxFocus = TextBoxFocus + 1
   PrintLabel TextBoxFocus, 15
  END IF
 END IF


 IF MouseLeftButton = -1 THEN
  FOR xx = 1 TO ActiveButtons
   IF (mousexpos >= Button(xx).x) AND (mousexpos <= Button(xx).x + Button(xx).lenght) AND (mouseypos >= Button(xx).y) AND (mouseypos <= Button(xx).y + 17) THEN
    DrawButtonDown xx
    ButtonFocus = xx
    DO WHILE MouseLeftButton = -1 AND (mousexpos >= Button(xx).x) AND (mousexpos <= Button(xx).x + Button(xx).lenght) AND (mouseypos >= Button(xx).y) AND (mouseypos <= Button(xx).y + 17)
     mouse 3
    LOOP
    DrawButton xx
   END IF
  NEXT xx
 END IF

END SUB

' 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$ = "speech error"

 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
IF ltr$ = "y" AND nltr$ = CHR$(32) THEN say$ = "e": ltr$ = ""
'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 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"

' 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 UpdateListBox (posi, top, way)

x = ListBox(posi).x
y = ListBox(posi).y
xlen = ListBox(posi).xlen
ylen = ListBox(posi).ylen
Text$ = ListBoxLabel$(posi)
NumItems = ListBox(posi).NumItems
show = ListBox(posi).show
top = ListBox(posi).top
prev = ListBox(posi).selected

IF way = 0 THEN
 IF ((top + show) - 1) = NumItems THEN
  PlayWarning
 ELSE
  top = top + 1
  LINE (x + 2, y + 2)-(x + xlen - 2, y + ylen - 2), 15, BF
  row = y
  row = row + 3
  ctr = 0
  FOR ff = 1 TO show
   fprint ListBoxContent$(posi, top + ctr), x + 5, row, 0, 2
   ctr = ctr + 1
   row = row + 10
  NEXT ff
 END IF
 ListBox(posi).top = top
 SetListBoxFocus posi, prev
 EXIT SUB
END IF

IF way = 1 THEN
 IF top = 1 THEN
  PlayWarning
 ELSE
  top = top - 1
  LINE (x + 2, y + 2)-(x + xlen - 2, y + ylen - 2), 15, BF
  row = y
  row = row + 3
  ctr = 0
  FOR ff = 1 TO show
   fprint ListBoxContent$(posi, top + ctr), x + 5, row, 0, 2
   ctr = ctr + 1
   row = row + 10
  NEXT ff
 END IF
 ListBox(posi).top = top
 SetListBoxFocus posi, prev
END IF

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 WriteToDSP (v%)
DO
LOOP UNTIL (INP(BlasterAddr% + &HC) AND 128) = 0
OUT BlasterAddr% + &HC, v%
END SUB

