[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]
{
> 4.I have all my GUS routines working, but can anyone point me to
> a place where I can get ANY *PUBLIC DOMAIN* SB/SBPro code which
> would help me play/mix digital samples? (I'm not talking
> CT-VOICE VOC code here...).
DSP.PAS - A demo SoundBlaster DSP unit for real mode
By Mark Feldman
}
Unit DSP;
Interface
{ ResetDSP returns true if reset was successful
base should be 1 for base address 210h, 2 for 220h etc... }
function ResetDSP(base : word) : boolean;
{ Write DAC sets the speaker output level }
procedure WriteDAC(level : byte);
{ ReadDAC reads the microphone input level }
function ReadDAC : byte;
{ SpeakerOn connects the DAC to the speaker }
function SpeakerOn: byte;
{ SpeakerOff disconnects the DAC from the speaker,
but does not affect the DAC operation }
function SpeakerOff: byte;
{ Functions to pause DMA playback }
procedure DMAStop;
procedure DMAContinue;
{ Playback plays a sample of a given size back at a given frequency using
DMA channel 1. The sample must not cross a page boundry }
procedure Playback(sound : Pointer; size : word; frequency : word);
Implementation
Uses Crt;
var DSP_RESET : word;
DSP_READ_DATA : word;
DSP_WRITE_DATA : word;
DSP_WRITE_STATUS : word;
DSP_DATA_AVAIL : word;
function ResetDSP(base : word) : boolean;
begin
base := base * $10;
{ Calculate the port addresses }
DSP_RESET := base + $206;
DSP_READ_DATA := base + $20A;
DSP_WRITE_DATA := base + $20C;
DSP_WRITE_STATUS := base + $20C;
DSP_DATA_AVAIL := base + $20E;
{ Reset the DSP, and give some nice long delays just to be safe }
Port[DSP_RESET] := 1;
Delay(10);
Port[DSP_RESET] := 0;
Delay(10);
if (Port[DSP_DATA_AVAIL] And $80 = $80) And
(Port[DSP_READ_DATA] = $AA) then
ResetDSP := true
else
ResetDSP := false;
end;
procedure WriteDSP(value : byte);
begin
while Port[DSP_WRITE_STATUS] And $80 <> 0 do;
Port[DSP_WRITE_DATA] := value;
end;
function ReadDSP : byte;
begin
while Port[DSP_DATA_AVAIL] and $80 = 0 do;
ReadDSP := Port[DSP_READ_DATA];
end;
procedure WriteDAC(level : byte);
begin
WriteDSP($10);
WriteDSP(level);
end;
function ReadDAC : byte;
begin
WriteDSP($20);
ReadDAC := ReadDSP;
end;
function SpeakerOn: byte;
begin
WriteDSP($D1);
end;
function SpeakerOff: byte;
begin
WriteDSP($D3);
end;
procedure DMAContinue;
begin
WriteDSP($D4);
end;
procedure DMAStop;
begin
WriteDSP($D0);
end;
procedure Playback(sound : Pointer; size : word; frequency : word);
var time_constant : word;
page, offset : word;
begin
SpeakerOn;
size := size - 1;
{ Set up the DMA chip }
offset := Seg(sound^) Shl 4 + Ofs(sound^);
page := (Seg(sound^) + Ofs(sound^) shr 4) shr 12;
Port[$0A] := 5;
Port[$0C] := 0;
Port[$0B] := $49;
Port[$02] := Lo(offset);
Port[$02] := Hi(offset);
Port[$83] := page;
Port[$03] := Lo(size);
Port[$03] := Hi(size);
Port[$0A] := 1;
{ Set the playback frequency }
time_constant := 256 - 1000000 div frequency;
WriteDSP($40);
WriteDSP(time_constant);
{ Set the playback type (8-bit) }
WriteDSP($14);
WriteDSP(Lo(size));
WriteDSP(Hi(size));
end;
end.
[Back to SOUND SWAG index] [Back to Main SWAG index] [Original]