Metropoli BBS
VIEWER: sndblst.pas MODE: TEXT (ASCII)
{soundblaster stuff}

procedure setintvek(intnro:byte; newhand:pointer);assembler; asm
mov ah,$25; mov al,[intnro]; push ds; lds dx,newhand;
int $21; pop ds; end; {like dos-setintvec}

function getintvek(intnro:byte):pointer;assembler; asm
mov ah,$35; mov al,[intnro]; int $21; mov dx,es;
mov ax,bx; end; {like dos-getintvec, except this one is a function}

procedure retrace; assembler;
asm
 mov dx,3dah;
 xor cx,cx;
@vert1:
 dec cx
 jz @vert2;

 in al,dx;
 test al,8;
 jz @vert1;
 xor cx,cx;
@vert2:
 dec cx
 jz @end;

 in al,dx;
 test al,8;
 jnz @vert2;
@end:;
end;

procedure writedsp(value:byte); assembler;
asm
 mov dx,dsp_write_status;
 xor cx,cx
@loop:
 dec cx
 jz @end;

 in al,dx;
 and al,$80;
 jnz @loop;
@end:

 mov dx,dsp_write_data;
 mov al,value;
 out dx,al;
end;

function readdsp:byte; assembler;
asm
 mov dx,dsp_data_avail;
 xor cx,cx;
@loop:
 dec cx
 jz @end;

 in al,dx;
 and al,$80;
 jz @loop;
@end:
 mov dx,dsp_read_data;
 in al,dx;
end;

procedure speakeron;
begin
  writedsp($D1);
end;

procedure speakeroff;
begin
  writedsp($D3);
end;

procedure dmacontinue;
begin
  writedsp($D4);
end;

procedure dmastop;
begin
  writedsp($D0);
end;

procedure odota; assembler;
asm
 mov dx,dsp_data_avail;
 xor cx,cx;
@loop:
 dec cx
 jz @end;

 in al,dx;
 and al,$80;
 jz @loop;
@end:
end;

function resetdsp(base:word; epatoivo:byte):boolean;
var eptoiv:byte;
    reset:boolean;
begin
 base:=base*$10+$200;
 dsp_reset:=base+$6;
 dsp_read_data:=base+$A;
 dsp_write_data:=base+$C;
 dsp_write_status:=base+$C;
 dsp_data_avail:=base+$E;
 eptoiv:=0;
 reset:=false;
 asm cli; end;
 port[$0D]:=$00; {from soundss3}
 repeat
  inc(eptoiv);
  port[dsp_reset]:=1;
  retrace; retrace; {just in case.. 1/20 of this should do}
  port[dsp_reset]:=0;
  retrace;
  odota;
  if readdsp=$AA then reset:=true else reset:=false;
 until (reset) or (eptoiv>epatoivo);
 asm sti; end;
 resetdsp:=reset;
end;

function setfreq(freq:word):word;
var t:integer;
begin
 writedsp($D1);
 writedsp($40);
 if freq<5000 then freq:=5000 else if freq>45454 then freq:=45454;
 case freq of
  05000..21738:t:=byte(256-(1000000 div freq));
  21739..45454:t:=byte(hi(65536-(256000000 div freq)));
 end;
 writedsp(byte(t));
 setfreq:=-1000000 div (t-256);
end;

procedure playback(sound:pointer; size:word;
                   startmask,stopmask,pageport:byte);
var page,offset:word;
begin
 dec(size,1);

 offset:=(seg(sound^) shl 4+ofs(sound^));
 page:=(seg(sound^)+ofs(sound^) shr 4) shr 12;

 asm cli; cli; end;

 port[$0A]:=stopmask; { dmamaskport}
 port[$0C]:=0;{ dmaclrptrport}

 port[$0B]:=(startmask and $FB) or $58;{ dmamodeport} {autoinit}

 port[2*startmask]:=lo(offset);{ dmabaseaddrport}
 port[2*startmask]:=hi(offset);{ dmabaseaddrport}
 port[2*startmask+1]:=lo(size);{ dmacountport}
 port[2*startmask+1]:=hi(size);{ dmacountport}
 port[pageport]:=page;{ dmapageport}
 port[$0A]:=startmask;{ dmamaskport}

 inc(size,1);
 size:=size div 2;
 dec(size,1);

 writedsp($48);
 writedsp(lo(size));
 writedsp(hi(size));
 writedsp($90); {autoinitialized hi-speed dmatransfer}
 asm sti; sti; end;
end;
[ RETURN TO DIRECTORY ]