home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
progmisc
/
hellsrc.zip
/
GS.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-09-29
|
19KB
|
716 lines
; GUS lowlevel interface.
.386p
code32 segment para public use32
assume cs:code32, ds:code32
include pmode.inc
public _gusrout, _gusport, _gusirq, _gusram
public _vccmnd, _vccntrl, _vcsbeg, _vclbeg, _vclend, _vcfreq, _vcpan, _vcvol
public _gustimerfreq, _gusnumvoices
public _gs_init, _gs_uninit, _gs_putram, _gs_getram
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; DATA
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
align 4
EXTRACRAP = 1 ; 0=no extras, 1=yes extras
aclbeg dd 32 dup(?) ; actual channel loop begin |
aclend dd 32 dup(?) ; actual channel loop end |
acfreq dw 32 dup(?) ; actual channel frequency value |
acpan db 32 dup(?) ; actual channel pan position |
acvol db 32 dup(?) ; actual channel volume (high byte) |
; |
_vccmnd db 16 dup(?) ; virtual channel command bits |
; bit 0: volume change
; bit 1: balance change
; bit 2: frequency change
; bit 3: sample note-on
_vccntrl db 16 dup(?) ; virtual channel voice control
; bit 3: enable loop
; bit 4: bi-directional loop
; bit 6: 0=forward, 1=reverse
_vcsbeg dd 16 dup(?) ; virtual channel sample begin
_vclbeg dd 16 dup(?) ; virtual channel loop begin
_vclend dd 16 dup(?) ; virtual channel loop end
_vcfreq dw 16 dup(?) ; virtual channel frequency value
_vcpan db 16 dup(?) ; virtual channel pan position
_vcvol db 16 dup(?) ; virtual channel volume (high byte)
vcacoff db 16 dup(0) ; virtual channel offset in actual
ormgusirqvect dd ? ; old real mode GF1 IRQ vector
gusport102 dw ? ; GUS port + 102h
gusport103 dw ? ; GUS port + 103h
gusport104 dw ? ; GUS port + 104h
gusport107 dw ? ; GUS port + 107h
_gusrout dd _ret ; routine to call on every timer tick
_gusport dw 220h
_gusirq db 11
_gusram db 0 ; 1=256k, 2=512k, 3=768k, 4=1024k
_gustimerfreq db 0cch ; =256-((1000000/Hz)/320)
_gusnumvoices db 0dfh ; =((Voices*2)-1)|0xc0
rmgusirqbuf db 21 dup(?) ; buffer for rm GF1 IRQ callback code
port103val db 43h ; value to set on exit from IRQ
irqm0tbl dw 0c089h,0a0e6h
gusirqvaltbl db 0,0,41h,43h,0,42h,0,44h,0,0,0,45h,46h,0,0,47h
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; CODE
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
;-----------------------------------------------------------------------------
@gusoutb macro index,value
mov al,&index
out dx,al
add dl,2
mov al,&value
out dx,al
sub dl,2
endm
@gusoutw macro index,value
mov al,&index
out dx,al
inc edx
mov ax,&value
out dx,ax
dec edx
endm
;═════════════════════════════════════════════════════════════════════════════
; GUS timer IRQ entry
irq:
push eax
mov al,20h
out 20h,al
irqm0 dw ? ; out 0a0h,al | mov eax,eax
sti
cld
push ebx ecx edx esi edi ebp ds
mov ds,cs:_seldata
mov dx,gusport103 ; reenable GUS timer
@outb 45h
add dl,2
@outb 0
@outb 8
call _gusrout
;-----------------------------------------------------------------------------
mov dx,gusport103
mov ebp,15
irql0:
xor cl,cl
xchg cl,_vccmnd[ebp]
or cl,cl
jz irql0c
movzx edi,vcacoff[ebp]
lea edi,[ebp*2+edi]
test cl,8
jz short irql0f0
xor vcacoff[ebp],1
mov eax,edi
dec edx
out dx,al
inc edx
mov bl,acvol[edi]
@gusoutb 7,4
@gusoutb 8,bl
@gusoutb 9,bl
@gusoutb 0dh,40h
xor edi,1
or cl,7
irql0f0:
mov eax,edi
dec edx
out dx,al
inc edx
test cl,4
jz short irql0f1
mov bx,_vcfreq[ebp*2]
cmp bx,acfreq[edi*2]
je short irql0f1
mov acfreq[edi*2],bx
@gusoutw 1,bx
irql0f1:
test cl,2
jz short irql0f2
mov bl,_vcpan[ebp]
cmp bl,acpan[edi]
je short irql0f2
mov acpan[edi],bl
@gusoutb 0ch,bl
irql0f2:
test cl,8
jz irql0f3
mov esi,_vclbeg[ebp*4]
cmp esi,aclbeg[edi*4]
je short irql0f2f0
mov aclbeg[edi*4],esi
shrd bx,si,7
shr esi,7
@gusoutw 2,si
@gusoutb 3,bh
irql0f2f0:
mov esi,_vclend[ebp*4]
cmp esi,aclend[edi*4]
je short irql0f2f1
mov aclend[edi*4],esi
shrd bx,si,7
shr esi,7
@gusoutw 4,si
@gusoutb 5,bh
irql0f2f1:
mov esi,_vcsbeg[ebp*4]
shrd bx,si,7
shr esi,7
@gusoutw 0ah,si
@gusoutb 0bh,bh
@gusoutb 0,_vccntrl[ebp]
irql0f3:
test cl,1
jz short irql0f4
mov bl,_vcvol[ebp]
mov bh,acvol[edi]
mov ah,bh
cmp bh,bl
je short irql0f4
mov ch,40h
ja short irql0f3f0
xchg bl,bh
xor ch,ch
irql0f3f0:
@gusoutb 7,bl
@gusoutb 8,bh
@gusoutb 9,ah
@gusoutb 0dh,ch
irql0f4:
mov dx,300h
db 7 dup(0ech) ; in al,dx
mov dx,gusport103
test cl,1
jz short irql0f5
mov al,_vcvol[ebp]
cmp al,ah
je short irql0f5
mov acvol[edi],al
@gusoutb 9,ah
@gusoutb 0dh,ch
irql0f5:
test cl,8
jz short irql0c
mov esi,_vcsbeg[ebp*4]
shrd bx,si,7
shr esi,7
@gusoutw 0ah,si
@gusoutb 0bh,bh
@gusoutb 0,_vccntrl[ebp]
xor edi,1
mov eax,edi
dec edx
out dx,al
inc edx
mov bl,4
xchg bl,acvol[edi]
@gusoutb 9,bl
@gusoutb 0dh,40h
irql0c:
sub ebp,1
jnc irql0
@outb port103val
;─────────────────────────────────────────────────────────────────────────────
irqdone:
pop ds ebp edi esi edx ecx ebx eax
iretd
;─────────────────────────────────────────────────────────────────────────────
; A small delay, In: ECX - number of times to do delay
gusdelay:
push ax dx
mov dx,300h
gusdelayl0:
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
loop gusdelayl0
pop dx ax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Shove some crap into GUS ram
; In:
; EBX - addx in GUS ram to shove into
; ECX - amount of crap to shove
; EDX -> actual crap to shove
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_putram:
push eax ebx ecx dx esi
mov esi,edx
mov dx,gusport104
gsputraml0:
dec edx
mov al,44h
mov port103val,al
out dx,al
add dl,2
shld eax,ebx,16
out dx,al
sub dl,2
mov al,43h
mov port103val,al
out dx,al
inc edx
gsputraml1:
mov ax,bx
out dx,ax
add dl,3
outsb
sub dl,3
inc bx
loopnz gsputraml1
jecxz short gsputramd
add ebx,10000h
jmp gsputraml0
gsputramd:
pop esi dx ecx ebx eax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Rip some crap outta GUS ram
; In:
; EBX - addx in GUS ram to rip from
; ECX - amount of crap to rip
; EDX -> buffer for ripped crap
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_getram:
push eax ebx ecx dx edi
mov edi,edx
mov dx,gusport104
gsgetraml0:
dec edx
mov al,44h
mov port103val,al
out dx,al
add dl,2
shld eax,ebx,16
out dx,al
sub dl,2
mov al,43h
mov port103val,al
out dx,al
inc edx
gsgetraml1:
mov ax,bx
out dx,ax
add dl,3
insb
sub dl,3
inc bx
loopnz gsgetraml1
jecxz short gsgetramd
add ebx,10000h
jmp gsgetraml0
gsgetramd:
pop edi dx ecx ebx eax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Initialize GUS sound system
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_init:
pushad
mov ax,900h
int 31h
push ax
mov dx,_gusport ; set up all port vars
@outb 0bh
add dx,102h
mov gusport102,dx
inc edx
mov gusport103,dx
inc edx
mov gusport104,dx
add dl,3
mov gusport107,dx
sub dl,4 ; initialize GUS
@outb 4ch
add dl,2
@outb 0
mov ecx,10h
call gusdelay
@outb 1
sub dl,2
mov ecx,10h
call gusdelay
@gusoutb 41h,0
@gusoutb 45h,0
@gusoutb 49h,0
@outb 0eh
add dl,2
@outb _gusnumvoices
sub dl,3
mov bl,1fh ; set up all voices
gsinitl0:
mov al,bl
and al,7fh
out dx,al
inc edx
@gusoutw 9,0
@gusoutb 0,0
@gusoutb 0dh,3
@gusoutb 6,16
@outb 0ch
add dl,2
@outb 7
sub dl,3
mov ecx,1
call gusdelay
xor bl,80h
js gsinitl0
sub bl,1
jnc gsinitl0
sub dx,0f3h ; damn, another undocumented port
@outb 5
sub dl,0fh
@outb 8
add dl,0bh
xor al,al
out dx,al
add dl,4
out dx,al
sub dl,0fh
movzx ebx,_gusirq ; set IRQ channels
@outb 4bh
add dl,0bh
mov al,gusirqvaltbl[ebx]
out dx,al
sub dl,0bh
@outb 9
add dx,103h
@outb 43h ; how much RAM on the card
inc edx
@outw 0ffffh
dec edx
@outb 44h
add dl,2
mov cl,3
gsinitl1:
@outb cl
add dl,2
in al,dx
inc eax
mov ah,al
out dx,al
in al,dx
sub dl,2
cmp al,ah
jne short gsinitl1d
inc _gusram
add cl,4
test cl,10h
jz gsinitl1
gsinitl1d:
sub dl,2
mov edi,offset aclbeg ; set some beginning values
mov ecx,80
mov eax,0ffffffffh
rep stosd
mov eax,7070707h
mov cl,8
rep stosd
xor eax,eax
mov cl,12
rep stosd
@gusoutb 4ch,3 ; enable GUS normal operation
@gusoutb 47h,_gustimerfreq ; start GUS timer
@outb 45h
add dl,2
@outb 8
sub dx,0fdh
@outb 4
inc edx
@outb 2
cmp bl,2 ; set and enable GF1 IRQ (BL=IRQ num)
jne short $+4
mov bl,9
cmp bl,7
seta al
movzx eax,al
mov ax,irqm0tbl[eax*2]
mov irqm0,ax
mov edx,offset irq
call _setirqvect
xor al,al
call _setirqmask
mov edi,offset rmgusirqbuf
call _rmpmirqset
mov ormgusirqvect,edx
pop ax
int 31h
popad
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Uninitialize GUS sound system
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_uninit:
push ax bx edx
mov ax,900h
int 31h
push ax
mov bl,_gusirq ; Kill GUS IRQ handler
cmp bl,2
jne short $+4
mov bl,9
mov edx,ormgusirqvect
call _rmpmirqfree
mov al,1
call _setirqmask
mov dx,gusport103 ; Shut down GUS
@outb 4ch
add dl,2
@outb 0
sub dx,105h
@outb 0bh
pop ax
int 31h
pop edx bx ax
ret
if EXTRACRAP ne 0
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; EXTRA CRAP
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
include kb.inc
extrn _putdosmsg:near
public _gs_find, _gs_ask, _gs_test
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; EXTRA CRAP DATA
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
pspultrastr db 'ULTRASND'
askmsg0 db 'Where''s the Ultrasound bub...?',0dh,0ah
db ' 0) I aint got one.',0dh,0ah
db ' 1) 210h.',0dh,0ah
db ' 2) 220h.',0dh,0ah
db ' 3) 230h.',0dh,0ah
db ' 4) 240h.',0dh,0ah
db ' 5) 250h.',0dh,0ah
db ' 6) 260h.',0dh,0ah
db 'ENTER) 220h and 11 (default).',0dh,0ah,'$'
askmsg1 db 0dh,0ah,'And what''s the magic IRQ number...?',0dh,0ah
db ' 0) 2',0dh,0ah
db ' 1) 3',0dh,0ah
db ' 2) 5',0dh,0ah
db ' 3) 7',0dh,0ah
db ' 4) 11',0dh,0ah
db ' 5) 12',0dh,0ah
db ' 6) 15',0dh,0ah,'$'
irqtbl db 2,3,5,7,11,12,15
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; EXTRA CRAP CODE
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Find a GUS (environment variable)
; Out:
; EAX,ECX,ESI,EDI - ?
; CF=0 - found GUS
; CF=1 - no GUS found
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_find:
mov esi,_pspa
movzx esi,word ptr gs:[esi+2ch]
shl esi,4
gsfindl3:
mov edi,offset pspultrastr
mov ecx,8
repe cmps byte ptr gs:[esi],byte ptr es:[edi]
jne short gsfindf0
mov edi,10h
call gsfindr0
mov _gusport,cx
call gsfindr0
call gsfindr0
mov edi,10
call gsfindr0
mov _gusirq,cl
clc
ret
gsfindf0:
lea esi,[esi+ecx-8]
gsfindl0:
inc esi
cmp byte ptr gs:[esi-1],0
jne gsfindl0
cmp byte ptr gs:[esi],0
jne gsfindl3
stc
ret
;-----------------------------------------------------------------------------
gsfindr0:
movzx eax,byte ptr gs:[esi]
inc esi
sub al,'0'
jc gsfindr0
cmp al,9
ja gsfindr0
mov ecx,eax
gsfindr0l0:
mov al,gs:[esi]
inc esi
sub al,'0'
jc gsfindr0d
cmp al,9
ja gsfindr0d
imul ecx,edi
add ecx,eax
jmp gsfindr0l0
gsfindr0d:
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Ask if GUS present and for port and IRQ
; Out:
; EAX,EDX - ?
; CF=0 - no GUS
; CF=1 - GUS be here
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_ask:
mov byte ptr _gusport,20h
mov _gusirq,11
mov edx,offset askmsg0
call _putdosmsg
gsaskl1:
call _getch
cmp al,13
je short gsaskd
sub al,'0'
jc gsaskl1
je short gsaska
cmp al,6
ja gsaskl1
shl al,4
mov byte ptr _gusport,al
mov edx,offset askmsg1
call _putdosmsg
gsaskl0:
call _getch
sub al,'0'
jc gsaskl0
cmp al,6
ja gsaskl0
movzx eax,al
mov al,irqtbl[eax]
mov _gusirq,al
gsaskd:
clc
ret
gsaska:
stc
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Test _gusport
; Out:
; AX,BL,DX - ?
; CF=0 - GUS failed
; CF=1 - GUS passed
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gs_test: ; Temporarily out of service
clc
ret
; mov ax,900h
; int 31h
; push ax
; mov dx,_gusport
; add dx,103h
; @outb 44h
; in al,dx
; cmp al,44h
; jne short gstesta
; add dl,2
; @outb 0
; sub dl,2
; @outb 43h
; inc edx
; @outw 0
; add dl,3
; in al,dx
; mov bl,al
; sub dl,3
; @outw 1
; add dl,3
; not bl
; @outb bl
; sub dl,3
; @outw 0
; add dl,3
; in al,dx
; cmp al,bl
; je short gstesta
; sub dl,3
; @outw 1
; add dl,3
; in al,dx
; cmp al,bl
; jne short gstesta
; clc
; pop ax
; int 31h
; ret
gstesta:
; stc
; pop ax
; int 31h
; ret
endif
code32 ends
end