'===========================================================================
' Subject: SOUND BLASTER TO SPEAKER           Date: 11-03-97 (02:02)       
'  Author: Andrew S. Gibson                   Code: QB, QBasic, PDS        
'  Origin: zapf_dingbat@juno.com            Packet: SOUND.ABC
'===========================================================================
'Hello fellow coders !  This little program is a cheap efficient way to
'play incoming audio from your Sound Blaster's Line-in or Microphone jack
'is you don't have an internal CD player or you want to use a cassette
'player. *You won't need to turn up the input volume very much at all !*
'This started as an experiment, but I turned it into a viable
'application. You need to load QuickBASIC with this switch /L, compile
'Sound Blaster to Speaker for optimal speed ! ý
'I've tested this using a 386sx running at 25Mhz and have been more than
'ecstatic with the output. I highly recommend that You shouldn't
'alter any of the code !
'Email me at this address is you desire: Zapf_DingBat@JUNO.COM
'My real name is Andrew Gibson and I *really* wrote 95% of the code !
'Not the sound blaster dectection code though..
'I have tested this with a Sound Blaster 2.0 (the only sound card I have!)
'Oh Yeah, I now have a 486sx 33Mhz based system, try it wherever you can !
'Once you compile this type SB2SPK /? for help.
'Release 2 / Update 1

DECLARE SUB Help ()
DEFINT A-Z
DECLARE SUB STDOUT (MESSAGETEXT$)
TYPE RegType
  AX    AS INTEGER
  BX    AS INTEGER
  CX    AS INTEGER
  DX    AS INTEGER
  BP    AS INTEGER
  SI    AS INTEGER
  DI    AS INTEGER
  FLAGS AS INTEGER
  DS    AS INTEGER
  ES    AS INTEGER
END TYPE

CONST TRUE = -1, FALSE = 0
DIM SHARED Registers AS RegType

IF COMMAND$ = "/?" OR COMMAND$ = "?" OR COMMAND$ = "/HELP" OR COMMAND$ = "HELP" THEN Help: GOTO Term
STDOUT "SB2SPK Version .51á" + CHR$(10) + CHR$(13)
'STDOUT "Sound Blaster routines by Gary Maddox, obtained from SB-Digest Issue #5" + CHR$(10) + CHR$(13)

 BPORT = &H210: XPORT = &H216: WPORT = &H21C: RPORT = &H21A
 APORT = &H21E: READY = &HAA

DO
   OUT XPORT, 1
 
   FOR T = 0 TO 10
   ll! = TIMER
   DO
   LOOP WHILE ll! = TIMER
   NEXT
   OUT XPORT, 0
   loopctr = 0
   DO
     byte = INP(RPORT)
     loopctr = loopctr + 1
   IF byte = &HAA THEN EXIT DO
   IF loopctr > 100 THEN EXIT DO
   LOOP
   IF byte <> &HAA THEN
     BPORT = BPORT + &H10
     XPORT = XPORT + &H10
     WPORT = WPORT + &H10
     RPORT = RPORT + &H10
 
     APORT = APORT + &H10
   END IF
 IF byte = &HAA THEN EXIT DO
 IF RPORT = &H270 THEN EXIT DO
 LOOP
 
 IF BPORT = &H270 THEN
   STDOUT "Sound Blaster Not Found!" + CHR$(10) + CHR$(13)
   GOTO Term
 ELSE
   STDOUT "Sound Blaster Installed at Port: " + HEX$(BPORT) + "h." + CHR$(10) + CHR$(13)
 END IF
   STDOUT "Press any key to stop and not go deaf." + CHR$(13)

'set pc speaker 6 bit digital mode
      OUT &H43, &HB6                   'Setup to make no sound
      OUT &H42, &HFF
      OUT &H42, 0
      OUT &H43, &H90                   'Setup to interrupt on terminal
                                       'count
      OneShot = INP(&H61) OR 3         'Puts the speaker in one shot mode
      OUT &H61, OneShot

' shovel data from SB DAC to speaker
DO
OUT WPORT, &H20
byte = INP(RPORT) \ 2
OUT 66, byte
' ý
' If you are testing this in the QuickBASIC environment you will probably
' want to comment the next line, however you should remember to uncomment
' the line for compilation of SB2SPK. You might even have to tweak this
' delay for the sound to be audible without a droning whine.
T = 0: DO: T = T + 1: LOOP UNTIL T = 124 '<- that number works for with my 486sx 33Mhz system.
LOOP UNTIL INKEY$ <> ""

'reset PIT and speaker
OUT &H43, &HB6
OneShot = INP(&H61) AND &HFC
OUT &H61, OneShot
STDOUT CHR$(10) + "Bye." + CHR$(10) + CHR$(13)
Term:
END

SUB Help
STDOUT "SB2SPK Version .60á" + CHR$(10) + CHR$(13) + CHR$(10) + CHR$(13)
STDOUT "Sound Blaster to PC Speaker samples the data input from the Microphone" + CHR$(10) + CHR$(13)
STDOUT "or LineIn Jack AND plays it through the Speaker in REALTIME !!!!!" + CHR$(10) + CHR$(13)
STDOUT "A fast CPU is highly recommended for the best possible sound..." + CHR$(10) + CHR$(13)
STDOUT "Coded by Andrew Gibson, have fun." + CHR$(10) + CHR$(13)
END SUB

SUB STDOUT (MESSAGETEXT$)
Registers.AX = &H4000
Registers.BX = &H1
Registers.CX = LEN(MESSAGETEXT$)
Registers.DS = VARSEG(MESSAGETEXT$)
Registers.DX = SADD(MESSAGETEXT$)
CALL InterruptX(&H21, Registers, Registers)
END SUB
