home *** CD-ROM | disk | FTP | other *** search
/ Deathday Collection / dday.bin / edit / dfe / sounder2.pas < prev    next >
Pascal/Delphi Source File  |  1994-05-26  |  4KB  |  251 lines

  1. unit Sounder2;
  2.  
  3.   {$C FIXED PRELOAD PERMANENT}
  4.   {$M 65520,64500,655350}
  5. interface
  6.  
  7. uses WadDecl;
  8.  
  9. var    SbIOAddr,SbIRQ:word;
  10.         DMA_Complete:boolean;
  11.  
  12. Function InitSB:boolean;
  13. Procedure SetSbIOAddr(NewAddr:word);
  14. Procedure SetSbIRQ(NewIRQ:word);
  15. Procedure SetVoice(State:integer);
  16. Procedure PlayBuff(sBuff:PSoundBuff;BuffAddr:longint);
  17. Procedure StopBuff;
  18. Function Sys_InitSB:Boolean;
  19. Procedure Sys_DoneSB;
  20.  
  21. Implementation
  22.  
  23. uses DOS,CRT;
  24.  
  25. CONST    DMA            =0;       {DMA Constants}
  26.         CH0_BASE     =0;
  27.         CH0_COUNT     =1;
  28.         CH1_BASE     =2;
  29.         CH1_COUNT     =3;
  30.         CH2_BASE     =4;
  31.         CH2_COUNT     =5;
  32.         CH3_BASE     =6;
  33.         CH3_COUNT     =7;
  34.         DMA_STATUS  =8;
  35.         DMA_CMD        =8;
  36.         DMA_REQUEST =9;
  37.         DMA_MASK        =10;
  38.         DMA_MODE        =11;
  39.         DMA_FF        =12;
  40.         DMA_TMP        =13;
  41.         DMA_CLEAR    =13;
  42.         DMA_CLRMSK    =14;
  43.         DMA_WRMSK    =15;
  44.         DMAPAGE        =$80;
  45.  
  46.         DSP_WRITE_STATUS    =$C;        {Sound Blaster Constants}
  47.         DSP_WRITE_DATA        =$C;
  48.  
  49. PROCEDURE cli;
  50. INLINE
  51.   (
  52.   $FA    {CLI}
  53.   );
  54.  
  55. PROCEDURE sti;
  56. INLINE
  57.   (
  58.   $FB    {STI}
  59.   );
  60.  
  61. {$F+}
  62.  
  63.  
  64. var    IRQVect:pointer;
  65.         OldExit:Pointer;
  66.  
  67. Function InitSB:boolean;
  68.  
  69.     var RetVal:Boolean;
  70.  
  71.     begin
  72.         asm
  73.              mov al,1
  74.              mov dx,sbIOaddr
  75.              add dx,6
  76.              out dx,al
  77.              in    al,dx
  78.              in    al,dx
  79.              in    al,dx
  80.              in    al,dx
  81.              mov al,0
  82.              out dx,al
  83.              add dx,4
  84.              mov cx,100
  85.         @@1:
  86.              in al,dx
  87.              cmp al,0AAh
  88.              je @@2
  89.              loop @@1
  90.              mov  RetVal,False
  91.              jmp @@3
  92.         @@2:
  93.              mov RetVal,True
  94.         @@3:
  95.         end;
  96.         InitSb:=RetVal;
  97.     end;
  98.  
  99. Procedure SetSbIOAddr(NewAddr:word);
  100.  
  101.     begin
  102.         SbIOAddr:=NewAddr;
  103.     end;
  104.  
  105. Procedure writeDAC(v:byte);
  106.  
  107.     var b:byte;
  108.  
  109.     begin
  110.         repeat
  111.             b:=port[sbIOAddr+DSP_WRITE_STATUS];
  112.         until (b and $80)=0;
  113.         port[sbIOAddr+DSP_WRITE_DATA]:=v;
  114.     end;
  115.  
  116. Procedure SetVoice(State:Integer);
  117.  
  118.     begin
  119.         case State of
  120.             1:writeDAC($D1);    {Voice On}
  121.             0:writeDAC($D3);    {Voice Off}
  122.         end;
  123.     end;
  124.  
  125. Procedure SetSampleRate(Rate:word);
  126.  
  127.     var    tc:byte;
  128.  
  129.     begin
  130.         tc:=(256 - (1000000 div rate));
  131.         writeDAC($40);
  132.         writeDAC(tc);
  133.     end;
  134.  
  135. Procedure SetPICStatus;
  136.  
  137.     var im,tm:byte;
  138.  
  139.     begin
  140.         im:=port[$21];
  141.         tm:=(1 shl sbIRQ) xor $FF;
  142.         port[$21]:=(im and tm);
  143.         sti;
  144.     end;
  145.  
  146. Procedure SetDMAStatus(BuffAddr:longint;DataLen:word);
  147.  
  148.     var    t:word;
  149.  
  150.     begin
  151.         {Set DMA Mode}
  152.         port[DMA_MASK]:=5;
  153.         port[DMA_FF]:=0;
  154.         port[DMA_MODE]:=$49;
  155.         {Set Transfer Address}
  156.         t:=(BuffAddr shr 16);
  157.       port[DMAPAGE+3]:=t;
  158.       t:=(BuffAddr and $FFFF);
  159.         port[CH1_BASE]:=(t and $FF);
  160.       port[CH1_BASE]:=(t shr 8);
  161.       {Set Transfer Length Byte Count}
  162.       port[CH1_COUNT]:=(DataLen and $FF);
  163.       port[CH1_COUNT]:=(DataLen shr 8) and $FF;
  164.       {Unmask DMA Channel}
  165.       port[DMA_MASK]:=1;
  166.    end;
  167.  
  168. Procedure SetDACStatus(DataLen:word);
  169.  
  170.     begin
  171.       {Set Up Sound Blaster for transfer}
  172.       writeDAC($48);        {Setup DAC for DMA Transfer}
  173.       writeDAC(DataLen and $FF);
  174.       writeDAC((DataLen shr 8) and $FF);
  175.       writeDAC($14);
  176.       writeDAC(DataLen and $FF);
  177.       writeDAC((DataLen shr 8) and $FF);
  178.     end;
  179.  
  180. {$F+,S-,W-}
  181. procedure IRQProc(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
  182.  
  183.     interrupt;
  184.    begin
  185.        STI;
  186.       DMA_Complete:=True;
  187.       port[$20]:=$20;
  188.    end;
  189. {$F-,S+}
  190.  
  191. Procedure SetSbIRQ(NewIRQ:word);
  192.  
  193.     begin
  194.        SbIRQ:=NewIRQ;
  195.    end;
  196.  
  197. Function Sys_InitSB:boolean;
  198.  
  199.     var    Regs:Registers;
  200.  
  201.     begin
  202.       if InitSB=False then begin
  203.          writeln('Sb_Init: Failed to initialize Sound Blaster.');
  204.            Halt(1);
  205.       end;
  206.       CLI;
  207.       GetIntVec($08+sbIRQ,IRQVect);
  208.       SetIntVec($08+sbIRQ,@IRQProc);
  209.       STI;
  210.       DMA_Complete:=False;
  211.       Sys_InitSB:=True;
  212.       SetVoice(1);
  213.     end;
  214.  
  215. Procedure Sys_DoneSB;
  216.  
  217.     begin
  218.       SetIntVec($08+sbIRQ,IRQVect);
  219.       ExitProc:=OldExit;
  220.       SetVoice(0);
  221.    end;
  222.  
  223. Procedure PlayBuff(sBuff:PSoundBuff;BuffAddr:longint);
  224.  
  225.     type TBuff=Array[0..46080] of byte;
  226.  
  227.     begin
  228.        DMA_complete:=False;
  229.       InitSB;
  230.       SetSampleRate(sBuff^.SampleRate);
  231.       SetPICStatus;
  232.         SetDMAStatus(BuffAddr,sBuff^.Samples);
  233.       SetDACStatus(sBuff^.Samples);
  234.       SetVoice(1);
  235.    end;
  236.  
  237. Procedure StopBuff;
  238.  
  239.     begin
  240.        SetVoice(0);
  241.    end;
  242.  
  243. begin
  244.     sbIOAddr:=$220;
  245.    sbIRQ:=5;
  246.    DMA_Complete:=False;
  247.    Sys_InitSb;
  248.    OldExit:=ExitProc;
  249.    ExitProc:=@Sys_DoneSB;
  250. end.
  251.