home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip: Special Sound & MIDI
/
Chip-Special_Sound-und-Midi-auf-dem-PC.bin
/
dosprog
/
vocbsp1.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-11-21
|
8KB
|
241 lines
(***C*H*I*P***S*P*E*C*I*A**L*************************************************)
(* *)
(* VOC-Beispiel 1: Sound-Wiedergabe über den digitalen Audiokanal *)
(* *)
(* (c) 1993 Rainer Reusch, Patrick Haller & Vogel Verlag München *)
(* *)
(* Turbo Pascal 7.0 *)
(* *)
(****************************************************************************)
{
Dieses Beispiel zeigt:
- die Initialisierung des Digital Sound Processors der Sound Blaster
- die direkte Wiedergabe eines 8-Bit-Sounds ohne Berücksichtigung einer
Abtastrate
}
{$A+,B-,D-,E+,F-,G+,I-,L-,N+,O-,P-,Q-,R-,S-,T-,V-,X+}
{$M 16384,0,655360}
program VOVBsp1;
uses
Dos, Crt;
type
{ Sound-Kartenparameter
(Reihenfolge nicht ändern, nichts einfügen, neue Parameter nur anhängen!) }
tBoardParams = record
PortAdr, { Portadresse }
IRQ, { Hardware-Interrupt }
DMA, { DMA-Kanal }
BoardType : word; { Kartentyp }
end { record };
const
{ Default-Sound-Kartenparameter }
DefBoardParams : tBoardParams =
( PortAdr : $220;
IRQ : 7;
DMA : 1;
BoardType : 1);
{ Indizes für Sound-Blaster-Register }
SB_Reset = $06; { DSP-Initialisierung }
SB_Write = $0C; { DSP-Befehlsregister }
SB_Data = $0A; { DSP-Datenregister }
SB_Status = $0E; { DSP-Statusregister }
{ -------------------------------------------------------------------------- }
function GetBoardParams(var BoardParams : tBoardParams) : boolean;
{ -------------------------------------------------------------------------- }
{ Diese Funktion sucht nach der Environmentvariablen "BLASTER" und ermittelt
daraus die Sound-Kartenkonfiguration. Das Funktionsergebnis ist true, wenn
die Variable gefunden wurde und alle vier Parameter (siehe Typvereinbarung
tBoardParams) angegeben sind. Fehlende Parameter werden durch Defaultwerte
(Variable DefBoardParams) ersetzt. }
function GetParamValue(var ParamLine : string; ParamCode : char;
var Value : word; IsHex : boolean) : boolean;
{ Ermittelt den Parameter aus einem String. Ergebnis true, wenn gefunden.
Value bleibt unverändert, wenn nicht gefunden. IsHex=true: Parameter ist
als Hexzahl aufzufassen. }
var
p : byte;
ss : string[5];
v : word;
e : integer;
begin
p:=Pos(ParamCode,ParamLine);
if p>0 then
begin { gewünschter Parameter gefunden }
GetParamValue:=true;
ss:=copy(ParamLine,p+1,5); { Ziffernstring extrahieren }
p:=Pos(#$20,ss);
if p>0 then ss[0]:=chr(p-1);
if IsHex then
begin { Parameter ist als Hexzahl aufzufassen }
if length(ss)>0 then
begin
v:=0;
e:=0;
for p:=1 to length(ss) do
begin
v:=v shl 4;
if (ss[p]>='0') and (ss[p]<='9') then v:=v+ord(ss[p])-48
else
if (ss[p]>='A') and (ss[p]<='F') then v:=v+ord(ss[p])-55
else inc(e);
end;
end
else GetParamValue:=false;
end
else val(ss,v,e); { Parameter ist als Dezimalzahl aufzufassen }
if e=0 then Value:=v
else GetParamValue:=false;
end
else GetParamValue:=false;
end { GetParamValue };
const
VarName = 'BLASTER'; { Name der zu suchenden Environmentvariablen }
var
Params : string[62];
Result : boolean;
begin
BoardParams:=DefBoardParams;
Params:=GetEnv(VarName);
Result:=GetParamValue(Params,'A',BoardParams.PortAdr,true);
Result:=Result and GetParamValue(Params,'I',BoardParams.IRQ,false);
Result:=Result and GetParamValue(Params,'D',BoardParams.DMA,false);
Result:=Result and GetParamValue(Params,'T',BoardParams.BoardType,false);
GetBoardParams:=Result;
end { GetBoardParams };
{ -------------------------------------------------------------------------- }
function SBInit(var BoardParams : tBoardParams) : boolean; assembler;
{ -------------------------------------------------------------------------- }
{ DSP der Sound Blaster initialisieren
Funktionsergebnis true, wenn Aktion erfolgreich. }
asm
push es
les bx,BoardParams { Adresse der Kartenparameter in ES:BX }
mov cx,es:[bx] { 1. Record-Variable (hier PortAdr) in CX }
mov dx,cx { und CX }
add dx,SB_Reset { Index für Reset-Register dazuaddieren }
mov al,1 { eine "1" auf Reset-Register ausgeben }
out dx,al
xor al,al { ein bißchen warten (mind. 3µs) }
@1:
nop
dec al
jnz @1
out dx,al { eine "0" auf Reset-Register ausgeben }
mov ax,2000h { nochmal ein bißchen warten }
@2:
nop
dec ax
jnz @2
mov dx,cx { Status ermitteln }
add dx,SB_Status
in al,dx
test al,80h { Bit 7 gesetzt? }
jz @NotOk { Sprung, wenn nein }
mov dx,cx { zusätzliche Prüfung }
add dx,SB_Data { aus dem DSP-Datenregister muß AAh gelesen werden }
in al,dx
cmp al,0AAh
jne @NotOk
mov ax,1 { Funktionsergebnis true }
jmp @Ready
@NotOk:
xor ax,ax { Funktionsergebnis false }
@Ready:
pop es
end { SBInit };
{ -------------------------------------------------------------------------- }
procedure SBWrite(PortAdr : word; Data : byte); assembler;
{ -------------------------------------------------------------------------- }
{ Übergabe eines Kommando- oder Datenbytes an DSP }
asm
mov dx,PortAdr { Basisadresse der Sound-Karte }
add dx,SB_Write { Index für Ausgaberegister hinzuaddieren }
@1:
in al,dx { Prüfen, ob der DSP zur Datenaufnahme bereits ist }
and al,80h
jnz @1
mov al,[Data] { Kommando bzw. Datenbyte ausgeben }
out dx,al
end { SBWrite };
{ -------------------------------------------------------------------------- }
procedure SBDAC(var BoardParams : tBoardParams; Data : byte);
{ -------------------------------------------------------------------------- }
{ "Wiedergabe" eines Datenbytes }
begin
SBWrite(BoardParams.PortAdr,$10); { Kommando 10h für DSP }
SBWrite(BoardParams.PortAdr,Data); { das Datenbyte gleich hinterher }
end { SBDAC };
const
MaxSample = 64000;
var
Board : tBoardParams;
b : byte;
i : word;
Sample : array[0..MaxSample] of byte;
begin
ClrScr;
writeln('*** VOC-Beispiel 1: Sound-Wiedergabe über den digitalen Audiokanal ***');
writeln;
{ Wo ist die Sound-Karte? }
if GetBoardParams(Board) then writeln('Im Environment eingetragene Parameter:')
else writeln('Parameter nicht gefunden! Verwendung von Defaultwerten.');
with Board do
begin
writeln(' PortAdresse (A): ',PortAdr);
writeln(' Hardware-Interrupt (I): ',IRQ);
writeln(' DMA-Kanal (D): ',DMA);
writeln(' Sound-Kartentyp (T): ',Boardtype);
end;
writeln;
{ der Demo-Sound wird hier mathematisch erzeugt }
writeln('Bitte etwas Geduld, Sound wird berechnet...');
for i:=0 to MaxSample do
begin
write(MaxSample-i,' ',#13);
Sample[i]:=round(128+63*sin(i/10*(i/1000)));
end;
writeln;
{ Wiedergabe }
writeln('Sound-Wiedergabe');
if not SBInit(Board) then
begin
writeln('Initialisierung der Sound Blaster fehlgeschlagen!');
Halt(1);
end;
SBWrite(Board.PortAdr,$D1); { DSP mit Verstärker verbinden }
for b:=0 to 3 do
for i:=0 to MaxSample do SBDAC(Board,Sample[i]);
end.