home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
AMOD095.ZIP
/
GUS.INC
< prev
next >
Wrap
Text File
|
1995-12-13
|
11KB
|
474 lines
{$s-}
Procedure GUSDelay; Assembler;
ASM
mov dx,gus_base
add dx,$100
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
End;
Function GUSPeek(Loc : Longint) : Byte;
Var
B : Byte;
AddLo : Word;
AddHi : Byte;
Begin
AddLo := Loc AND $FFFF;
AddHi := LongInt(Loc AND $FF0000) SHR 16;
Port [gus_base+$103] := $43;
Portw[gus_base+$104] := AddLo;
Port [gus_base+$103] := $44;
Port [gus_base+$105] := AddHi;
B := Port[gus_base+$107];
GUSPeek := B;
End;
Procedure GUSPoke(Loc : Longint; B : Byte);
Var
AddLo : Word;
AddHi : Byte;
Begin
AddLo := Loc AND $FFFF;
AddHi := longint(Loc and $ff0000) shr 16;
Port [gus_base+$103] := $43;
Portw[gus_base+$104] := AddLo;
Port [gus_base+$103] := $44;
Port [gus_base+$105] := AddHi;
Port [gus_base+$107] := B;
End;
Function GUSProbe(adr : word) : Boolean;
Var
B: Byte;
ogus_base : word;
Begin
ogus_base := gus_base;
gus_base := adr;
Port [gus_base+$103] := $4C;
Port [gus_base+$105] := 0;
GUSDelay;
GUSDelay;
Port [gus_base+$103] := $4C;
Port [gus_base+$105] := 1;
GUSPoke(0, $AA);
GUSPoke($100, $55);
B := GUSPeek(0);
gus_base := ogus_base;
If B = $AA then GUSProbe := True else GUSProbe := False;
End;
Procedure GUSFind;
Var
I : Word;
b : word;
Begin
if gus_base < $210 then begin
i := 1;
while i < 8 do begin
B := $200 + I*$10;
If GUSProbe(b) then I := 8;
inc(i);
End;
if b < $280 then gus_base := b
else gus_base := $200;
end;
if gus_base <> $200 then begin
active_voice := gus_base+_active_voice;
command := gus_base+_command;
data_low := gus_base+_data_low;
data_high := gus_base+_data_high;
dram_io := gus_base+_dram_io;
end;
End;
Function GUSFindMem : Longint;
{ Returns how much RAM is available on the GUS }
Var
I : Longint;
B : Byte;
Begin
GUSPoke($40000, $AA);
If GUSPeek($40000) <> $AA then I := $3FFFF
else
Begin
GUSPoke($80000, $AA);
If GUSPeek($80000) <> $AA then I := $8FFFF
else
Begin
GUSPoke($C0000, $AA);
If GUSPeek($C0000) <> $AA then I := $CFFFF
else I := $FFFFF;
End;
End;
guspoke(0,$aa);
if guspeek(0) <> $aa then i := 0;
GUSFindMem := I;
End;
Procedure GUSSetFreq( V : Byte; hz : Word); assembler;
asm
cli
mov dx,active_voice
mov al,v
out dx,al
mov dx,command
mov al,1
out dx,al
mov dx,data_low
mov ax,hz
out dx,ax
{Port [gus_base+$102] := V;
Port [gus_base+$103] := 1;
Portw[gus_base+$104] := hz;}
sti
end;
Procedure GUSVoiceControl( V, B : Byte);
Begin
asm cli end;
Port [gus_base+$102] := V;
Port [gus_base+$103] := $0;
Port [gus_base+$105] := B;
asm sti end;
End;
Procedure GUSSetBalance( V, Bal : Byte); assembler;
asm
cli
mov dx,active_voice
mov al,v
out dx,al
mov dx,command
mov al,0ch
out dx,al
mov dx,data_high
mov al,bal
out dx,al
{Port [active_voice] := V;
Port [command] := $C;
Port [data_high] := Bal;}
sti
End;
Procedure GUSSetVolume( V : Byte; Vol : Word); assembler;
asm
cli
mov dx,active_voice
mov al,v
out dx,al {Port [active_voice] := V;}
mov dx,command
mov al,0dh
out dx,al {port [command] := $d;}
mov dx,data_high
mov al,2
out dx,al {port [data_high] := 2;}
mov dx,command
mov al,9
out dx,al {Port [command] := 9;}
mov dx,data_low
mov ax,vol
out dx,ax {Portw[data_low] := Vol;} { 0-0ffffh, log ... not linear }
sti
End;
Procedure GUSStopVoice( V : Byte);
Var
Temp : Byte;
Begin
asm cli end;
Port [active_voice] := V;
port [command] := $d;
port [data_high] := 2;
Port [command] := 9;
Portw[data_low] := 0;
port[command] := $d;
port[data_high] := 2;
Port [command] := $80;
Temp := Port[data_high];
Port [command] := 0;
Port [data_high] := (Temp AND $df) OR 3;
asm sti end;
End;
Procedure GUSPlayVoice( V, Mode : word;VBegin, VStart, VEnd : Longint);
Begin
asm cli end;
Port [active_voice] := V;
port [command] := 0;
port [data_high] := 2; {stop voice}
Port [command] := $0A;
Portw[data_low] := (VBegin SHR 7) AND 8191;
Port [command] := $0B;
Portw[data_low] := (VBegin AND 127) SHL 9;
Port [command] := $02;
Portw[data_low] := (VStart SHR 7) AND 8191;
Port [command] := $03;
Portw[data_low] := (VStart AND 127) SHL 9;
Port [command] := $04;
Portw[data_low] := ((VEnd) SHR 7) AND 8191;
Port [command] := $05;
Portw[data_low] := ((VEnd) AND 127) SHL 9;
Port [command] := $0;
Port [data_high] := Mode and $fe;
asm sti end;
end;
Procedure GUSPlayAll( V, Mode : word;VBegin, VStart, VEnd : Longint;
freq,vol : word); assembler;
asm
cli
mov dx,active_voice {Port [active_voice] := V;}
mov ax,v
out dx,al
mov si,command {port [command] := $d;}
mov di,data_high
mov dx,si
mov al,0dh
out dx,al
mov dx,di
mov al,2
out dx,al {port[data_high] := 2;}
mov dx,si
mov al,9
out dx,al {port[command] := 9;}
mov dx,data_low
mov ax,0
out dx,ax {port[data_low] := vol;}
mov dx,si
mov al,0
out dx,al
mov dx,di {port [data_high] := 2;} {stop voice}
mov al,2
out dx,al
mov dx,si
mov al,9
out dx,al {port [command] := 9;}
mov dx,data_low
mov ax,vol
out dx,ax {portw[data_low] := vol;} {set volume}
mov dx,si
mov al,1
out dx,al {port [command] := 1;}
mov dx,data_low
mov ax,freq
out dx,ax {portw[data_low] := freq;}
mov dx,si
mov al,0ah
out dx,al {Port [command] := $0A;}
mov dx,data_low
mov bx,word ptr vbegin+2
shl bx,16-7
mov ax,word ptr vbegin
shr ax,7
or ax,bx
and ax,8191
out dx,ax {Portw[data_low] := (VBegin SHR 7);}
mov dx,si
mov al,0bh
out dx,al {Port [command] := $0B;}
mov dx,data_low
mov ax,word ptr vbegin
and ax,127
shl ax,9
out dx,ax {Portw[data_low] := (VBegin AND 127) SHL 9;}
mov dx,si
mov al,02h
out dx,al {Port [command] := $02;}
mov dx,data_low
mov bx,word ptr vstart+2
shl bx,16-7
mov ax,word ptr vstart
shr ax,7
or ax,bx
and ax,8191
out dx,ax {Portw[data_low] := (VStart SHR 7);}
mov dx,si
mov al,03h
out dx,al {Port [command] := $03;}
mov dx,data_low
mov ax,word ptr vstart
and ax,127
shl ax,9
out dx,ax {Portw[data_low] := (VStart AND 127) SHL 9;}
mov dx,si
mov al,04h
out dx,al {Port [command] := $04;}
mov dx,data_low
mov bx,word ptr vend+2
shl bx,16-7
mov ax,word ptr vend
shr ax,7
or ax,bx
and ax,8191
out dx,ax {Portw[data_low] := (VEnd SHR 7);}
mov dx,si
mov al,05h
out dx,al {Port [command] := $05;}
mov dx,data_low
mov ax,word ptr vend
and ax,127
shl ax,9
out dx,ax {Portw[data_low] := (Vend AND 127) SHL 9;}
mov dx,si
xor al,al
out dx,al {Port [command] := $0;}
mov dx,di
mov ax,mode
and ax,0feh
out dx,al {Port [data_high] := Mode and $fe;}
sti
end;
procedure gussetramp(chn,vstart,vend,rate : integer);
var
i : integer;
begin
asm cli end;
port[active_voice] := chn;
port[command] := $d;
port[data_high] := 2;
port[command] := 9;
portw[data_low] := vstart shl 8;
port[command] := 6;
port[data_high] := rate;
if vend > vstart then i := 0
else begin
i := $40;
asm
mov ax,vstart
xchg ax,vend
mov vstart,ax
end;
end;
port[command] := 8;
port[data_high] := vend;
port[command] := 7;
port[data_high] := vstart;
port[command] := $d;
port[data_high] := i;
asm sti end;
end;
procedure GusSetOfs(v : byte;vbegin : longint);
begin
asm cli end;
Port [active_voice] := V;
Port [command] := $0A;
Portw[data_low] := (VBegin SHR 7) AND 8191;
Port [command] := $0B;
Portw[data_low] := (VBegin AND 127) SHL 9;
asm sti end;
end;
procedure gussetchns(chns : integer);
{chns = number of chns-1}
var
n : integer;
begin
port [gus_base+_command] := $0E;
port [gus_base+_data_high] := (chns) OR $0C0;
Port [gus_base+_command] := $44;
Port [gus_base+_data_high] := 0;
Port [gus_base+_command] := $43;
Portw[gus_base+_data_low] := 0;
Port [gus_base+_dram_io] := 0;
Port [gus_base+_command] := $43;
Portw[gus_base+_data_low] := 1;
Port [gus_base+_dram_io] := 0;
for n := 0 to chns do begin
port[gus_base+_active_voice] := n;
port[gus_base+_command] := 0; {stop voice}
port[gus_base+_data_high] := 2;
port[gus_base+_command] := $d; {clear ramp}
port[gus_base+_data_high] := 2;
port[gus_base+_command] := $a; {set current location to 0}
portw[gus_base+_data_low] := 0;
port[gus_base+_command] := $b;
portw[gus_base+_data_low] := 0;
port[gus_base+_command] := 9; {set volume to 0}
portw[gus_base+_data_low] := 0;
end;
end;
Procedure GUSReset;
var
n : integer;
Begin
port[gus_base+_command] := $4C;
port[gus_base+_data_high] := 0;
for n := 0 to 9 do gusdelay;
port[gus_base+_command] := $4c;
port[gus_base+_data_high] := 1;
for n := 0 to 9 do gusdelay;
port[gus_base+_command] := $41;
port[gus_base+_data_high] := 0;
{ Clear all interrupts }
PORT[gus_base+_command] := DMA_Control;
PORT[gus_base+Data_High] := $00;
PORT[gus_base+_command] := TIMER_Control;
PORT[gus_base+Data_High] := $00;
PORT[gus_base+_command] := SAMPLE_Control;
PORT[gus_base+Data_High] := $00;
port [gus_base+_command] := $0E;
port [gus_base+_data_high] := (13 OR $0C0);
gussetchns(13);
n := port[gus_base+6];
Port[gus_base+_command] := $4C;
Port[gus_base+_data_high] := 7;
gusdelay;
{ Set up FOR Digital ASIC }
PORT[gus_base+$0F] := 5;
PORT[gus_base] := $0b;
PORT[gus_base+$b] := 0;
PORT[gus_base+$0F] := 0;
port[gus_base] := 1+8;
n := gus_info[1];
End;
procedure gusdeinit;
var
n : word;
begin
gussetchns(13);
for n := 0 to 13 do gusstopvoice(n);
end;