home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Equalizer BBS
/
equalizer-bbs-collection_2004.zip
/
equalizer-bbs-collection
/
DEMOSCENE-STUFF
/
TIMESRC.ZIP
/
LOW_GUS.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-02-24
|
16KB
|
616 lines
; Low level Gravis Ultrasound interface by Tran (a.k.a. Thomas Pytel)
.386p
code32 segment para public use32
assume cs:code32, ds:code32
include pmode.inc
include low_data.inc
public _gus_data
public voltbl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; DATA
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
align 4
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) |
vcacoff db 16 dup(0) ; virtual channel offset in actual
ormgusirqvect dd ? ; old real mode GF1 IRQ vector
freqfactor dw ?, 0 ; frequency calculation factor
gusport102 dw ? ; GUS port + 102h
gusport103 dw ? ; GUS port + 103h
gusport104 dw ? ; GUS port + 104h
gusport107 dw ? ; GUS port + 107h
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 ; opcodes for IRQ levels (0-7,8-15)
gusirqvaltbl db 0,0,41h,43h,0,42h,0,44h,0,0,0,45h,46h,0,0,47h
voltbl db 004h,0a0h,0b0h,0c0h,0c8h,0d0h,0d8h,0e0h
db 0e4h,0e8h,0ech,0f0h,0f2h,0f4h,0f6h,0f8h
freqfactortbl dw 44100,38587,34300,30870,28063,25725,23746,22050
dw 20580,19293
align 4
_gus_data dd _gus_init, _gus_uninit, _gus_set_bps, _ret
dd _gus_set_voices, _gus_get_freq, _gus_put_data
dd _gus_get_data, _ret
db 00000111b ; info bitmap
; bit 0: 0=system RAM, 1=card RAM
; bit 1: port needed
; bit 2: IRQ number needed
; bit 3: DMA number needed
; bit 4: Mixing rate selectable
db 'Gravis Ultrasound',0,'$'
;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
; 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 _low_rout
;-----------------------------------------------------------------------------
mov dx,gusport103
mov ebp,15
irql0:
xor cl,cl
xchg cl,_low_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,_low_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,_low_vcpan[ebp]
cmp bl,acpan[edi]
je short irql0f2
mov acpan[edi],bl
@gusoutb 0ch,bl
irql0f2:
test cl,8
jz irql0f3
mov esi,_low_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,_low_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,_low_vcsbeg[ebp*4]
shrd bx,si,7
shr esi,7
@gusoutw 0ah,si
@gusoutb 0bh,bh
@gusoutb 0,_low_vccntrl[ebp]
irql0f3:
test cl,1
jz short irql0f4
movzx esi,_low_vcvol[ebp]
shr esi,4
mov bl,voltbl[esi]
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
movzx esi,_low_vcvol[ebp]
shr esi,4
mov al,voltbl[esi]
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,_low_vcsbeg[ebp*4]
shrd bx,si,7
shr esi,7
@gusoutw 0ah,si
@gusoutb 0bh,bh
@gusoutb 0,_low_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
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Initialize low level GUS system
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_init:
pushad
mov ax,900h
int 31h
push ax
mov dx,_low_port ; 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 at full voices
@outb 4ch
add dl,2
@outb 0
mov ecx,10h
call initr0
@outb 1
sub dl,2
mov ecx,10h
call initr0
@gusoutb 41h,0
@gusoutb 45h,0
@gusoutb 49h,0
@outb 0eh
add dl,2
@outb 0dfh
sub dl,3
mov bl,1fh ; set up all voices
initl0:
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 initr0
xor bl,80h
js initl0
sub bl,1
jnc initl0
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,_low_irq ; 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
xor esi,esi
mov cl,3
initl1:
@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 initl1d
add esi,40000h
add cl,4
test cl,10h
jz initl1
initl1d:
mov _low_ram,esi
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,8
rep stosd
@gusoutb 4ch,3 ; enable GUS normal operation
@gusoutb 47h,0cch ; start GUS timer at 60Hz
@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
mov edi,offset rmgusirqbuf
call _rmpmirqset
mov ormgusirqvect,eax
xor al,al
call _setirqmask
xor eax,eax ; initial clicks here, not at muz beg
mov _low_buf,eax
mov _low_rambase,eax
mov dword ptr _low_vcvol[0],eax
mov dword ptr _low_vcvol[4],eax
mov dword ptr _low_vcvol[8],eax
mov dword ptr _low_vcvol[12],eax
mov dword ptr _low_vccntrl[0],eax
mov dword ptr _low_vccntrl[4],eax
mov dword ptr _low_vccntrl[8],eax
mov dword ptr _low_vccntrl[12],eax
mov edi,offset _low_vcsbeg
mov ecx,32
rep stosd
mov ah,1
mov ecx,24
rep stosd
mov eax,7070707h
rep stosd
mov eax,8080808h
mov dword ptr _low_vccmnd[0],eax
mov dword ptr _low_vccmnd[4],eax
mov dword ptr _low_vccmnd[8],eax
mov dword ptr _low_vccmnd[12],eax
pop ax
int 31h
popad
ret
;-----------------------------------------------------------------------------
initr0:
push ax dx
mov dx,300h
initr0l0:
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
loop initr0l0
pop dx ax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Uninitialize low level GUS system
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_uninit:
push eax ebx edx
mov ax,900h
int 31h
push ax
mov bl,_low_irq
cmp bl,2
jne short $+4
mov bl,9
mov eax,ormgusirqvect
call _rmpmirqfree
mov al,1
call _setirqmask
mov dx,gusport103
@outb 4ch
add dl,2
@outb 0
sub dx,105h
@outb 0bh
pop ax
int 31h
pop edx ebx eax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Set beats per second
; In:
; AL - beats per second (15-255)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_set_bps:
push ax bx dx
movzx bx,al
mov ax,900h
int 31h
push ax
xor dx,dx
mov ax,3125
div bx
mov bl,al
neg bl
mov dx,gusport103
@gusoutb 47h,bl
pop ax
int 31h
pop dx bx ax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Set number of active voices
; In:
; AL - number of voices (1-16)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_set_voices:
push ax edx
movzx edx,al
mov ax,900h
int 31h
push ax
cmp dl,7
jae short $+4
mov dl,7
shl dl,1
mov ax,freqfactortbl[edx-14]
mov freqfactor,ax
dec edx
mov ah,dl
mov dx,gusport103
@outb 0eh
add dl,2
or ah,0c0h
@outb ah
pop ax
int 31h
pop edx ax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Convert actual frequency to GUS frequency number
; In:
; EAX - frequency
; Out:
; AX - GUS frequency number
; EAX high word - ?
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_get_freq:
push edx
xor edx,edx
shl eax,10
div dword ptr freqfactor
pop edx
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Put sample data into GUS ram
; In:
; EBX - addx in GUS ram to put to
; ECX - length in bytes to put
; EDX -> sample data to put
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_put_data:
push eax ebx ecx dx esi
mov esi,edx
mov dx,gusport104
putdatal0:
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
putdatal1:
mov ax,bx
out dx,ax
add dl,3
outsb
sub dl,3
inc bx
loopnz putdatal1
jecxz short putdatad
add ebx,10000h
jmp putdatal0
putdatad:
pop esi dx ecx ebx eax
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Get sample data from GUS ram
; In:
; EBX - addx in GUS ram to get from
; ECX - length in bytes to get
; EDX -> buffer for sample data
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_gus_get_data:
push eax ebx ecx dx edi
mov edi,edx
mov dx,gusport104
getdatal0:
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
getdatal1:
mov ax,bx
out dx,ax
add dl,3
insb
sub dl,3
inc bx
loopnz getdatal1
jecxz short getdatad
add ebx,10000h
jmp getdatal0
getdatad:
pop edi dx ecx ebx eax
ret
code32 ends
end