home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / AMOD095.ZIP / GUS.INC < prev    next >
Text File  |  1995-12-13  |  11KB  |  474 lines

  1. {$s-}
  2. Procedure GUSDelay; Assembler;
  3. ASM
  4.   mov   dx,gus_base
  5.   add   dx,$100
  6.   in    al, dx
  7.   in    al, dx
  8.   in    al, dx
  9.   in    al, dx
  10.   in    al, dx
  11.   in    al, dx
  12.   in    al, dx
  13. End;
  14.  
  15. Function  GUSPeek(Loc : Longint) : Byte;
  16. Var
  17.   B : Byte;
  18.   AddLo : Word;
  19.   AddHi : Byte;
  20. Begin
  21.   AddLo := Loc AND $FFFF;
  22.   AddHi := LongInt(Loc AND $FF0000) SHR 16;
  23.  
  24.   Port [gus_base+$103] := $43;
  25.   Portw[gus_base+$104] := AddLo;
  26.   Port [gus_base+$103] := $44;
  27.   Port [gus_base+$105] := AddHi;
  28.  
  29.   B := Port[gus_base+$107];
  30.   GUSPeek := B;
  31. End;
  32.  
  33.  
  34. Procedure GUSPoke(Loc : Longint; B : Byte);
  35. Var
  36.   AddLo : Word;
  37.   AddHi : Byte;
  38. Begin
  39.   AddLo := Loc AND $FFFF;
  40.   AddHi := longint(Loc and $ff0000) shr 16;
  41.   Port [gus_base+$103] := $43;
  42.   Portw[gus_base+$104] := AddLo;
  43.   Port [gus_base+$103] := $44;
  44.   Port [gus_base+$105] := AddHi;
  45.   Port [gus_base+$107] := B;
  46. End;
  47.  
  48.  
  49. Function GUSProbe(adr : word) : Boolean;
  50. Var
  51.   B: Byte;
  52.   ogus_base : word;
  53. Begin
  54.   ogus_base := gus_base;
  55.   gus_base := adr;
  56.   Port [gus_base+$103] := $4C;
  57.   Port [gus_base+$105] := 0;
  58.   GUSDelay;
  59.   GUSDelay;
  60.   Port [gus_base+$103] := $4C;
  61.   Port [gus_base+$105] := 1;
  62.   GUSPoke(0, $AA);
  63.   GUSPoke($100, $55);
  64.   B := GUSPeek(0);
  65.   gus_base := ogus_base;
  66.   If B = $AA then GUSProbe := True else GUSProbe := False;
  67. End;
  68.  
  69.  
  70. Procedure GUSFind;
  71. Var
  72.   I : Word;
  73.   b : word;
  74. Begin
  75.   if gus_base < $210 then begin
  76.     i := 1;
  77.     while i < 8 do begin
  78.       B := $200 + I*$10;
  79.       If GUSProbe(b) then I := 8;
  80.       inc(i);
  81.     End;
  82.     if b < $280 then gus_base := b
  83.     else gus_base := $200;
  84.   end;
  85.   if gus_base <> $200 then begin
  86.     active_voice := gus_base+_active_voice;
  87.     command := gus_base+_command;
  88.     data_low := gus_base+_data_low;
  89.     data_high := gus_base+_data_high;
  90.     dram_io := gus_base+_dram_io;
  91.   end;
  92. End;
  93.  
  94. Function  GUSFindMem : Longint;
  95. { Returns how much RAM is available on the GUS }
  96. Var
  97.   I : Longint;
  98.   B : Byte;
  99. Begin
  100.   GUSPoke($40000, $AA);
  101.   If GUSPeek($40000) <> $AA then I := $3FFFF
  102.     else
  103.   Begin
  104.     GUSPoke($80000, $AA);
  105.     If GUSPeek($80000) <> $AA then I := $8FFFF
  106.       else
  107.     Begin
  108.       GUSPoke($C0000, $AA);
  109.       If GUSPeek($C0000) <> $AA then I := $CFFFF
  110.         else I := $FFFFF;
  111.     End;
  112.   End;
  113.   guspoke(0,$aa);
  114.   if guspeek(0) <> $aa then i := 0;
  115.   GUSFindMem := I;
  116. End;
  117.  
  118. Procedure GUSSetFreq( V : Byte; hz : Word); assembler;
  119. asm
  120.   cli
  121.   mov  dx,active_voice
  122.   mov  al,v
  123.   out  dx,al
  124.   mov  dx,command
  125.   mov  al,1
  126.   out  dx,al
  127.   mov  dx,data_low
  128.   mov  ax,hz
  129.   out  dx,ax
  130.  
  131.   {Port [gus_base+$102] := V;
  132.   Port [gus_base+$103] := 1;
  133.   Portw[gus_base+$104] := hz;}
  134.   sti
  135. end;
  136.  
  137. Procedure GUSVoiceControl( V, B : Byte);
  138. Begin
  139.   asm cli end;
  140.   Port [gus_base+$102] := V;
  141.   Port [gus_base+$103] := $0;
  142.   Port [gus_base+$105] := B;
  143.   asm sti end;
  144. End;
  145.  
  146. Procedure GUSSetBalance( V, Bal : Byte); assembler;
  147. asm
  148.   cli
  149.  
  150.   mov  dx,active_voice
  151.   mov  al,v
  152.   out  dx,al
  153.   mov  dx,command
  154.   mov  al,0ch
  155.   out  dx,al
  156.   mov  dx,data_high
  157.   mov  al,bal
  158.   out  dx,al
  159.  
  160.   {Port [active_voice] := V;
  161.   Port [command] := $C;
  162.   Port [data_high] := Bal;}
  163.   sti
  164. End;
  165.  
  166. Procedure GUSSetVolume( V : Byte; Vol : Word); assembler;
  167. asm
  168.     cli
  169.     mov  dx,active_voice
  170.     mov  al,v
  171.     out  dx,al           {Port [active_voice] := V;}
  172.     mov  dx,command
  173.     mov  al,0dh
  174.     out  dx,al           {port [command] := $d;}
  175.     mov  dx,data_high
  176.     mov  al,2
  177.     out  dx,al           {port [data_high] := 2;}
  178.     mov  dx,command
  179.     mov  al,9
  180.     out  dx,al           {Port [command] := 9;}
  181.     mov  dx,data_low
  182.     mov  ax,vol
  183.     out  dx,ax           {Portw[data_low] := Vol;}  { 0-0ffffh, log ... not linear }
  184.     sti
  185. End;
  186.  
  187. Procedure GUSStopVoice( V : Byte);
  188. Var
  189.   Temp : Byte;
  190. Begin
  191.   asm cli end;
  192.   Port [active_voice] := V;
  193.   port [command] := $d;
  194.   port [data_high] := 2;
  195.   Port [command] := 9;
  196.   Portw[data_low] := 0;
  197.  
  198.   port[command] := $d;
  199.   port[data_high] := 2;
  200.   Port [command] := $80;
  201.   Temp := Port[data_high];
  202.   Port [command] := 0;
  203.   Port [data_high] := (Temp AND $df) OR 3;
  204.   asm sti end;
  205. End;
  206.  
  207.  
  208. Procedure GUSPlayVoice( V, Mode : word;VBegin, VStart, VEnd : Longint);
  209. Begin
  210.   asm cli end;
  211.   Port [active_voice] := V;
  212.   port [command] := 0;
  213.   port [data_high] := 2;         {stop voice}
  214.  
  215.   Port [command] := $0A;
  216.   Portw[data_low] := (VBegin SHR 7) AND 8191;
  217.   Port [command] := $0B;
  218.   Portw[data_low] := (VBegin AND 127) SHL 9;
  219.   Port [command] := $02;
  220.   Portw[data_low] := (VStart SHR 7) AND 8191;
  221.   Port [command] := $03;
  222.   Portw[data_low] := (VStart AND 127) SHL 9;
  223.   Port [command] := $04;
  224.   Portw[data_low] := ((VEnd)   SHR 7) AND 8191;
  225.   Port [command] := $05;
  226.   Portw[data_low] := ((VEnd)   AND 127) SHL 9;
  227.  
  228.   Port [command] := $0;
  229.   Port [data_high] := Mode and $fe;
  230.   asm sti end;
  231. end;
  232.  
  233. Procedure GUSPlayAll( V, Mode : word;VBegin, VStart, VEnd : Longint;
  234.                       freq,vol : word); assembler;
  235.   asm
  236.     cli
  237.     mov  dx,active_voice  {Port [active_voice] := V;}
  238.     mov  ax,v
  239.     out  dx,al
  240.  
  241.     mov  si,command        {port [command] := $d;}
  242.     mov  di,data_high
  243.     mov  dx,si
  244.     mov  al,0dh
  245.     out  dx,al
  246.  
  247.     mov   dx,di
  248.     mov   al,2
  249.     out   dx,al            {port[data_high] := 2;}
  250.  
  251.     mov   dx,si
  252.     mov   al,9
  253.     out   dx,al            {port[command] := 9;}
  254.  
  255.     mov   dx,data_low
  256.     mov   ax,0
  257.     out   dx,ax            {port[data_low] := vol;}
  258.  
  259.     mov  dx,si
  260.     mov  al,0
  261.     out  dx,al
  262.     mov  dx,di      {port [data_high] := 2;}     {stop voice}
  263.     mov  al,2
  264.     out  dx,al
  265.  
  266.     mov  dx,si
  267.     mov  al,9
  268.     out  dx,al             {port [command] := 9;}
  269.     mov  dx,data_low
  270.     mov  ax,vol
  271.     out  dx,ax             {portw[data_low] := vol;}      {set volume}
  272.  
  273.     mov  dx,si
  274.     mov  al,1
  275.     out  dx,al            {port [command] := 1;}
  276.     mov  dx,data_low
  277.     mov  ax,freq
  278.     out  dx,ax            {portw[data_low] := freq;}
  279.  
  280.     mov  dx,si
  281.     mov  al,0ah
  282.     out  dx,al            {Port [command] := $0A;}
  283.     mov  dx,data_low
  284.     mov  bx,word ptr vbegin+2
  285.     shl  bx,16-7
  286.     mov  ax,word ptr vbegin
  287.     shr  ax,7
  288.     or   ax,bx
  289.     and  ax,8191
  290.     out  dx,ax            {Portw[data_low] := (VBegin SHR 7);}
  291.     mov  dx,si
  292.     mov  al,0bh
  293.     out  dx,al            {Port [command] := $0B;}
  294.     mov  dx,data_low
  295.     mov  ax,word ptr vbegin
  296.     and  ax,127
  297.     shl  ax,9
  298.     out  dx,ax            {Portw[data_low] := (VBegin AND 127) SHL 9;}
  299.  
  300.     mov  dx,si
  301.     mov  al,02h
  302.     out  dx,al            {Port [command] := $02;}
  303.     mov  dx,data_low
  304.     mov  bx,word ptr vstart+2
  305.     shl  bx,16-7
  306.     mov  ax,word ptr vstart
  307.     shr  ax,7
  308.     or   ax,bx
  309.     and  ax,8191
  310.     out  dx,ax            {Portw[data_low] := (VStart SHR 7);}
  311.     mov  dx,si
  312.     mov  al,03h
  313.     out  dx,al            {Port [command] := $03;}
  314.     mov  dx,data_low
  315.     mov  ax,word ptr vstart
  316.     and  ax,127
  317.     shl  ax,9
  318.     out  dx,ax            {Portw[data_low] := (VStart AND 127) SHL 9;}
  319.  
  320.     mov  dx,si
  321.     mov  al,04h
  322.     out  dx,al            {Port [command] := $04;}
  323.     mov  dx,data_low
  324.     mov  bx,word ptr vend+2
  325.     shl  bx,16-7
  326.     mov  ax,word ptr vend
  327.     shr  ax,7
  328.     or   ax,bx
  329.     and  ax,8191
  330.     out  dx,ax            {Portw[data_low] := (VEnd SHR 7);}
  331.     mov  dx,si
  332.     mov  al,05h
  333.     out  dx,al            {Port [command] := $05;}
  334.     mov  dx,data_low
  335.     mov  ax,word ptr vend
  336.     and  ax,127
  337.     shl  ax,9
  338.     out  dx,ax            {Portw[data_low] := (Vend AND 127) SHL 9;}
  339.  
  340.     mov  dx,si
  341.     xor  al,al
  342.     out  dx,al           {Port [command] := $0;}
  343.  
  344.     mov  dx,di
  345.     mov  ax,mode
  346.     and  ax,0feh
  347.     out  dx,al           {Port [data_high] := Mode and $fe;}
  348.     sti
  349. end;
  350.  
  351. procedure gussetramp(chn,vstart,vend,rate : integer);
  352. var
  353. i : integer;
  354. begin
  355.   asm cli end;
  356.   port[active_voice] := chn;
  357.   port[command] := $d;
  358.   port[data_high] := 2;
  359.   port[command] := 9;
  360.   portw[data_low] := vstart shl 8;
  361.   port[command] := 6;
  362.   port[data_high] := rate;
  363.   if vend > vstart then i := 0
  364.   else begin
  365.     i := $40;
  366.     asm
  367.       mov  ax,vstart
  368.       xchg ax,vend
  369.       mov  vstart,ax
  370.     end;
  371.   end;
  372.   port[command] := 8;
  373.   port[data_high] := vend;
  374.   port[command] := 7;
  375.   port[data_high] := vstart;
  376.   port[command] := $d;
  377.   port[data_high] := i;
  378.   asm sti end;
  379. end;
  380.  
  381. procedure GusSetOfs(v : byte;vbegin : longint);
  382. begin
  383.   asm cli end;
  384.   Port [active_voice] := V;
  385.   Port [command] := $0A;
  386.   Portw[data_low] := (VBegin SHR 7) AND 8191;
  387.   Port [command] := $0B;
  388.   Portw[data_low] := (VBegin AND 127) SHL 9;
  389.   asm sti end;
  390. end;
  391.  
  392. procedure gussetchns(chns : integer);
  393. {chns = number of chns-1}
  394. var
  395. n : integer;
  396. begin
  397.   port [gus_base+_command]   := $0E;
  398.   port [gus_base+_data_high] := (chns) OR $0C0;
  399.   Port [gus_base+_command] := $44;
  400.   Port [gus_base+_data_high] := 0;
  401.   Port [gus_base+_command] := $43;
  402.   Portw[gus_base+_data_low] := 0;
  403.   Port [gus_base+_dram_io] := 0;
  404.   Port [gus_base+_command] := $43;
  405.   Portw[gus_base+_data_low] := 1;
  406.   Port [gus_base+_dram_io] := 0;
  407.   for n := 0 to chns do begin
  408.     port[gus_base+_active_voice] := n;
  409.     port[gus_base+_command] := 0;     {stop voice}
  410.     port[gus_base+_data_high] := 2;
  411.     port[gus_base+_command] := $d;    {clear ramp}
  412.     port[gus_base+_data_high] := 2;
  413.     port[gus_base+_command] := $a;    {set current location to 0}
  414.     portw[gus_base+_data_low] := 0;
  415.     port[gus_base+_command] := $b;
  416.     portw[gus_base+_data_low] := 0;
  417.     port[gus_base+_command] := 9;     {set volume to 0}
  418.     portw[gus_base+_data_low] := 0;
  419.   end;
  420. end;
  421.  
  422. Procedure GUSReset;
  423. var
  424. n : integer;
  425. Begin
  426.   port[gus_base+_command]   := $4C;
  427.   port[gus_base+_data_high] := 0;
  428.   for n := 0 to 9 do gusdelay;
  429.   port[gus_base+_command] := $4c;
  430.   port[gus_base+_data_high] := 1;
  431.   for n := 0 to 9 do gusdelay;
  432.  
  433.   port[gus_base+_command] := $41;
  434.   port[gus_base+_data_high] := 0;
  435.  
  436.     { Clear all interrupts }
  437.     PORT[gus_base+_command] := DMA_Control;
  438.     PORT[gus_base+Data_High] := $00;
  439.     PORT[gus_base+_command] := TIMER_Control;
  440.     PORT[gus_base+Data_High] := $00;
  441.     PORT[gus_base+_command] := SAMPLE_Control;
  442.     PORT[gus_base+Data_High] := $00;
  443.  
  444.   port [gus_base+_command]   := $0E;
  445.   port [gus_base+_data_high] := (13 OR $0C0);
  446.  
  447.   gussetchns(13);
  448.  
  449.   n := port[gus_base+6];
  450.  
  451.   Port[gus_base+_command] := $4C;
  452.   Port[gus_base+_data_high] := 7;
  453.   gusdelay;
  454.  
  455.   { Set up FOR Digital ASIC }
  456.   PORT[gus_base+$0F] := 5;
  457.   PORT[gus_base] := $0b;
  458.   PORT[gus_base+$b] := 0;
  459.   PORT[gus_base+$0F] := 0;
  460.  
  461.   port[gus_base] := 1+8;
  462.   n := gus_info[1];
  463. End;
  464.  
  465.  
  466. procedure gusdeinit;
  467. var
  468. n : word;
  469. begin
  470.   gussetchns(13);
  471.   for n := 0 to 13 do gusstopvoice(n);
  472. end;
  473.  
  474.