home *** CD-ROM | disk | FTP | other *** search
/ Intermedia 1998 January / inter1_98.iso / www / rozi / RAW1.ZIP / MGPSB.PAS < prev    next >
Pascal/Delphi Source File  |  1995-01-04  |  7KB  |  247 lines

  1. {****************************************************************************}
  2. {*                                                                          *}
  3. {*                              MegaPlay v.2.0                              *}
  4. {*                          Sound Blaster Routines                          *}
  5. {*                                                                          *}
  6. {****************************************************************************}
  7. Unit MGPSB;
  8. INTERFACE
  9. Uses CRT;
  10. var
  11.  sbLocation:byte;
  12.  
  13. const
  14.  Toff:boolean=FALSE;
  15.  Stereo:boolean=FALSE;
  16.  SBPro:boolean=FALSE;
  17.  
  18.  sbReset=$206;        { Write }
  19.  sbWriteCmd=$20C;     { Write }
  20.  sbWriteStat=$20C;    { Read  }
  21.  sbDataAvail=$20E;    { Read  }
  22.  sbReadData=$20A;     { Read  }
  23.  sbpMixerAddr=$204;   { Write }
  24.  sbpMixerData=$205;   { ReadWrite }
  25.  sbpmControl=$0E;
  26.  sbpmMasterVol=$22;
  27.  sbpmFMVol=$26;
  28.  
  29. procedure StopAll;
  30. procedure Playback(sound : Pointer; xsize : word; tc:byte);
  31. procedure FadeVol(v:byte);
  32. procedure SetVolume(Volume:byte);
  33. procedure Speaker(OnOff:boolean);
  34. procedure WriteDSP(data:byte);
  35. function  DetectCard:byte;
  36. procedure SetOutMode(Stereo:boolean);
  37. function  ResetDSP:boolean;
  38. procedure WriteDAC(level : byte);
  39. IMPLEMENTATION
  40. {****************************************************************************}
  41. procedure sbOut(Base:word;data:byte);
  42. begin
  43. port[Base+sbLocation]:=data;
  44. end;
  45. {****************************************************************************}
  46. function  sbIn(Base:word):byte;
  47. begin
  48. sbIn:=port[Base+sbLocation];
  49. end;
  50. {****************************************************************************}
  51. procedure WaitWrite;assembler;
  52. label LoopWait,EndLoop;
  53. asm
  54.                         push    cx
  55.                         xor     cx,cx           { need that for slow SBs ! }
  56. loopWait:               dec     cx
  57.                         jz      endloop
  58.                         in      al,dx           { AL = WRITE COMMAND STATUS }
  59.                         or      al,al
  60.                         js      loopWait        { Jump if bit7=1 - writing not allowed }
  61. endloop:                pop     cx
  62.  
  63. end;
  64.  
  65. {****************************************************************************}
  66. procedure StopAll;
  67. begin
  68. Speaker(False);
  69. WriteDSP($D0);
  70. WriteDSP($DA);
  71. WriteDSP($D0);
  72. Toff:=TRUE;
  73. end;
  74. {****************************************************************************}
  75. procedure Playback;
  76. var page, offset : word;
  77. begin
  78.  
  79.   Speaker(TRUE);
  80.  
  81.   xsize := xsize - 1;
  82.  
  83.   { Set up the DMA chip }
  84.   offset := Seg(sound^) Shl 4 + Ofs(sound^);
  85.   page := (Seg(sound^) + Ofs(sound^) shr 4) shr 12;
  86.   Port[$0A] := 5;
  87.   Port[$0C] := 0;
  88.   Port[$0B] := $49;
  89.   Port[$02] := Lo(offset);
  90.   Port[$02] := Hi(offset);
  91.   Port[$83] := page;
  92.   Port[$03] := Lo(xsize);
  93.   Port[$03] := Hi(xsize);
  94.   Port[$0A] := 1;
  95.  
  96.   { Set the playback frequency }
  97.   WriteDSP($40);
  98.   WriteDSP(tc);
  99.  
  100.   { Set the playback type (8-bit) }
  101.   WriteDSP($14);
  102.   WriteDSP(Lo(xsize));
  103.   WriteDSP(Hi(xsize));
  104. end;
  105.  
  106. {****************************************************************************}
  107. procedure FadeVol;
  108. begin
  109. v:=v shr 4 + v shl 4;
  110. repeat
  111. if v and $F>0 then dec(v,1);
  112. if v and $F0>0 then dec(v,$10);
  113. SetVolume(v);
  114. delay(100);
  115. until v=0;
  116. end;
  117. {****************************************************************************}
  118. procedure SetVolume;
  119. begin
  120.   sbOut(sbpMixerAddr,sbpmMasterVol);
  121.   sbOut(sbpMixerData,Volume);
  122. end;
  123. {****************************************************************************}
  124. procedure Speaker;
  125. begin
  126. if onoff then WriteDSP($D1) else WriteDSP($D3);
  127. end;
  128. {****************************************************************************}
  129. procedure WriteDSP(data:byte);
  130. begin
  131. WaitWrite;
  132. sbOut(sbWriteCmd,data);
  133. end;
  134. {****************************************************************************}
  135. function DetectCard:byte;
  136. {****************************************************************************}
  137. {* Detects a Sound Card                                                     *}
  138. {* Returns:                                                                 *}
  139. {*  0 - None                                                                *}
  140. {*  1 - SB                                                                  *}
  141. {*  2 - SB Pro                                                              *}
  142. {****************************************************************************}
  143. var
  144. IOloc,t,Return:byte;
  145. sbOk,EndSearch:boolean;
  146. DSPV:array[1..2] of byte;
  147. begin
  148. Return:=0;
  149. IOloc:=$10;
  150. sbOk:=FALSE;
  151. EndSearch:=FALSE;
  152. { Search for SB through different base addresses }
  153. repeat
  154. sbLocation:=IOloc;
  155. sbOut(sbReset,1);
  156. asm
  157.    mov    dx,$388                { Wait >4usec }
  158.    in    al, dx
  159.    in    al, dx
  160.    in    al, dx
  161.    in    al, dx
  162.    in    al, dx
  163.    in    al, dx
  164.    in    al, dx
  165.    in    al, dx
  166.    in    al, dx
  167. end;
  168. sbOut(sbReset,0);
  169. asm
  170.    mov    dx,$388                { Wait >100usec }
  171.    mov    cx,100
  172. @@1:
  173.     in    al,dx
  174.     loop @@1
  175. end;
  176. for t:=0 to 100 do
  177.  begin
  178.  if sbIn(sbDataAvail) and $80>0 then
  179.   begin
  180.    if sbIn(sbReadData)=$AA then
  181.     begin
  182.     EndSearch:=TRUE;      { SB found }
  183.     SBOk:=TRUE;
  184.     end;
  185.   end;
  186.  end;
  187. inc(IOloc,$10);
  188. if IOloc=7 then
  189.  begin
  190.  EndSearch:=TRUE;
  191.  SBOk:=FALSE;
  192.  end;
  193. until EndSearch;
  194. if sbOk then Return:=1;
  195. { Try Mixer Chip : Detect SB Pro }
  196. sbOk:=false;
  197. sbOut(sbpMixerAddr,sbpmFMVol);
  198. sbOut(sbpMixerData,$bb);
  199. t:=sbIn(sbpMixerData);
  200. if t=$bb then
  201.  begin
  202.  sbOut(sbpMixerData,$ff);
  203.  t:=sbIn(sbpMixerData);
  204.  if t=$ff then
  205.   begin
  206.   sbOk:=true;
  207.   end;
  208.  end;
  209. if sbOk and (Return=1) then Return:=2;
  210. DetectCard:=Return;
  211. end;
  212. {****************************************************************************}
  213. procedure SetOutMode;
  214. begin
  215.   if Stereo then
  216.   begin
  217.   sbOut(sbpMixerAddr,sbpmControl);
  218.   sbOut(sbpMixerData,2);
  219.   end
  220.   else
  221.   begin
  222.   sbOut(sbpMixerAddr,sbpmControl);
  223.   sbOut(sbpMixerData,0);
  224.   end;
  225. end;
  226. {****************************************************************************}
  227. function ResetDSP;
  228. begin
  229.   sbOut(sbReset,1);
  230.   Delay(10);
  231.   sbOut(sbReset,0);
  232.   Delay(10);
  233.   if (sbIn(sbDataAvail) And $80 = $80) And
  234.      (sbIn(sbReadData) = $AA) then
  235.     ResetDSP := true
  236.   else
  237.     ResetDSP := false;
  238. end;
  239. {****************************************************************************}
  240. procedure WriteDAC;
  241. begin
  242.   WriteDSP($10);
  243.   WriteDSP(level);
  244. end;
  245. {****************************************************************************}
  246. END.
  247.