[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]

    {
    From: LENNERT BAKKER
    Subj: SB AutoDetect
        Here's how to autodetect a soundblaster and it's baseaddress
        and some other support-stuff for your convenience: }

    { Hey let's check this SB out 8-)}

    Const SBReset     = $6;
          SBRead      = $A;
          SBWrite     = $C;
          SBStatus    = $E;

    Var   SBPort      : Word;
          SBInstalled : Boolean;

    Procedure DetectSoundBlaster;
    Const NrTimes           = 10;
          NrTimes2          = 50;
    Var   Found             : Boolean;
          Counter1,Counter2 : Word;
    Begin
     SBPort:=$210;
     Found:=False;
     Counter1:=NrTimes;
      While (SBPort<=$260) And Not Found Do
       Begin
        Port[SBPort+$6]:=1;
        Port[SBPort+$6]:=0;
        Counter2:=NrTimes2;
         While (Counter2>0) And (Port[SBPort+$E]<128) Do
          Dec(Counter2);
         If (Counter2=0) Or (Port[SBPort+$A]<>$AA) Then
          Begin
           Dec(Counter1);
            If (Counter1=0) Then
             Begin
              Counter1:=NrTimes;
              SBPort:=SBPort+$10;
             End
          End Else Found:=True;
       End;
      If Found then SBInstalled:=True
       Else SBInstalled:=False;
    End;

    Begin
     DetectSoundBlaster;
      If SBInstalled then
       Writeln('SoundBlaster found at port :', SBPort)
      else
       Writeln('No soundcard, no boogie!');
    End.

    {Here's how to initialize the DSP:}

    Procedure SetupSoundBlaster;
    Var I,BDum : Byte;
    Begin
      If SBInstalled then
       Begin
        Port[SBPort+SBReset]:=1; {Reset DSP}
         For I:=1 to 6 do
          BDum:=Port[SBPort+SBStatus];
        Port[SBPort+SBReset]:=0;
         For I:=1 to 6 do
          BDum:=Port[SBPort+SBStatus];
         Repeat Until Port[SBPort+SBStatus]>$80;
       End;
    End;

    {Respectively turn the speaker on/off}

    Procedure TurnOnSBSpeaker;
    Begin
     Repeat Until Port[SBPort+SBWrite]<$80;
     Port[SBPort+SBWrite]:=$D1;
    End;

    Procedure TurnOffSBSpeaker;
    Begin
     Repeat Until Port[SBPort+SBWrite]<$80;
     Port[SBPort+SBWrite]:=$D3;
    End;

    {
      Here's basically how you play a sample, you should reprogram
      the timer though and have your interrupt routine output bytes
      to the DSP at regular intervals, say 10000 times/sec or so.
      Rather use machine-language instead, but that shouldn't be too
      hard now, should it? 8)
    }

    Procedure PlaySample(Sample:Pointer;Length:Word);
    Var A : Word;
    Begin
     For A:=1 to Length Do
      Begin
       Port[SBPort+SBWrite]:=$10;
       Port[SBPort+SBWrite]:=Mem[Seg(Sample^):Ofs(Sample^)+A];
       {Delay some time}
      End;
    End;

    {Or sumtin like this (untested) }

    Procedure PlaySampleASM(Sample:Pointer;Length:Word); Assembler;
    Asm
     Les Di,[Sample]
     Mov Dx,SBPort+SBWrite
     Mov Cx,Length
    @LoopIt:
     LodsB
     Out Dx,$10
     Out Dx,Al

     { Delay Some Time -- What about 1000 NOPs or so ;-) }

     Loop @LoopIt
    End;

[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]