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

{
CL±    Come to speak of this...  do you (or anyone) know which ports to zap the
CL±    data to for the SB to get it to play?  Or better yet, even how to get it
CL±    to play in DMA transfer mode?

Try this code.
}
(* A unit to provide basic control over a Sound Blaster or compatible card.*)
(* It works by reading and writing to the standard Sound Blaster ports.    *)
(* Released to the public domain by Brian Grainger, Sparwood, BC.          *)

UNIT SoundBlaster;

(*********************************)INTERFACE(********************************)

PROCEDURE sbSetAddressDelay(StereoMode : BYTE);
PROCEDURE sbSetDataDelay(StereoMode : BYTE);
PROCEDURE sbSetDataReg(RegNum, Value, StereoMode : BYTE);
FUNCTION  sbGetStatus(StereoMode : BYTE) : BYTE;
PROCEDURE sbResetTimers;
PROCEDURE sbEnableInterrupts;
PROCEDURE sbTurnOff;
FUNCTION  sbIsInstalled : BOOLEAN;

(*******************************)IMPLEMENTATION(*****************************)

CONST
  cMono  = 0;
  cLeft  = 1;
  cRight = 2;

VAR
  vStatus1 : BYTE;
  vStatus2 : BYTE;
  vDelay   : BYTE;
  vI       : BYTE;

PROCEDURE sbSetAddressDelay(StereoMode : BYTE);
  BEGIN
    FOR vI := 0 TO 5 DO
      CASE StereoMode OF
        cMono  : vDelay := Port[$388];
        cLeft  : vDelay := Port[$220];
        cRight : vDelay := Port[$222];
      END;
  END;

PROCEDURE sbSetDataDelay(StereoMode : BYTE);
  BEGIN
    FOR vI := 0 TO 34 DO
      CASE StereoMode OF
        cMono  : vDelay := Port[$388];
        cLeft  : vDelay := Port[$220];
        cRight : vDelay := Port[$222];
      END;
  END;

PROCEDURE sbSetDataReg(RegNum, Value, StereoMode : BYTE);
  BEGIN
    CASE StereoMode OF
      cMono  : Port[$388] := RegNum;
      cLeft  : Port[$220] := RegNum;
      cRight : Port[$222] := RegNum;
    END;
    sbSetAddressDelay(StereoMode);
    CASE StereoMode OF
      cMono  : Port[$389] := Value;
      cLeft  : Port[$221] := Value;
      cRight : Port[$222] := Value;
    END;
    sbSetDataDelay(StereoMode);
  END;

FUNCTION sbGetStatus(StereoMode : BYTE) : BYTE;
  BEGIN
    sbGetStatus := 0;
    CASE StereoMode OF
      cMono  : sbGetStatus := Port[$388];
      cLeft  : sbGetStatus := Port[$220];
      cRight : sbGetStatus := Port[$222];
    END;
  END;

PROCEDURE sbResetTimers;
  BEGIN
    sbSetDataReg($04, $60, cMono);
  END;

PROCEDURE sbEnableInterrupts;
  BEGIN
    sbSetDataReg($04, $80, cMono);
  END;

PROCEDURE sbTurnOff;
  BEGIN
    FOR vI := $01 TO $F5 DO
      sbSetDataReg(vI, $00, cMono);
  END;

FUNCTION sbIsInstalled : BOOLEAN;
  BEGIN
    sbIsInstalled := FALSE;
    sbResetTimers;
    sbEnableInterrupts;
    vStatus1 := sbGetStatus(cMono);
    sbSetDataReg($02, $FF, cMono);  (* Set timer 1 data register *)
    sbSetDataReg($04, $21, cMono);  (* Start timer 1             *)
    FOR vI := 1 TO 4 DO
      sbSetDataDelay(cMono);        (* Wait at least 80 uSeconds *)
    vStatus2 := sbGetStatus(cMono);
    sbResetTimers;
    sbEnableInterrupts;
    IF (((vStatus1 AND $E0) = $00) AND ((vStatus2 AND $E0) = $C0)) THEN
      sbIsInstalled := TRUE;
  END;
END.

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