home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
s
/
scrd_asm.zip
/
ADLIBAPI.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-06-17
|
7KB
|
246 lines
comment *
Purpose: API for producing sounds through AdLib
Author: Yousuf J. Khan
*
include adlib.inc ;include macros
.model tiny
.code
public delay
delay proc near
comment *
Purpose:
Produces a variable length delay on an AdLib or SoundBlaster
card, by reading the address port a number of times. Just the
act of calling a procedure, and doing a CX loop should add
delays of its own, so this is a very conservative procedure.
There should be more than enough delay here.
Entry:
CX: # of loops to produce (six loops after writing to address
port, or thirty-five loops after writing to data port).
Exit:
nothing.
*
push dx
mov dx, 388h ;AdLib address port at PC port 388h
call sbdelay ;call generalized delay procedure
pop dx
ret
endp
public sbdelay
sbdelay proc near
comment *
Purpose:
Same as the Delay procedure, except the port has to be set ahead
of time. More generalized procedure.
Entry:
DX: status/address port i/o address
CX: # of loops to produce (six loops after writing to address
port, or thirty-five loops after writing to data port).
Exit:
nothing.
*
push ax
delayloop:
in al, dx ;read address port
loop delayloop
pop ax
ret
endp
public adlibinit
adlibinit proc near
comment *
Purpose:
Initializes AdLib registers to zero
Entry:
nothing.
Exit:
nothing.
*
mov al, 1
zeroing_loop:
push ax
mov dx, 388h
out dx, al ;writing to address port
addrdelay
mov al, 0 ;zero the data register
mov dx, 389h
out dx, al
datadelay
pop ax
inc al
; there are only 245 AdLib registers (from 01h-F5h)
cmp al, 0F5h ;as long as AL is between
jbe short zeroing_loop ; 01-F5h, continue looping
ret
endp
public detect_adlib
detect_adlib proc near
comment *
Purpose:
To detect whether an AdLib-compatible is installed
Entry:
nothing.
Exit:
AX=0, if no AdLib
AX=1, if AdLib present
*
push dx ;save DX before tests begin
setadlib 4,60h ;reset both Adlib timers
setadlib 4,80h ;enable Adlib interrupts
mov dx, 388h ;Status/Addr port
in al, dx ;gives state#1
test al, 0E0h ;AND state#1 with E0h
jne short noAdLib ;if 0 then goto next test
;start 2nd state test
setadlib 2,0FFh ;writing FFh to Adlib timer#1
setadlib 4,21h ;start timer#1
mov cx, 145 ;145 iteration loop,
call delay ; or approx. 80ms delay
mov dx, 388h ;Status/Addr port
in al, dx ;gives state#2
and al, 0E0h ;AND state#2 with E0h
cmp al, 0C0h ;is state#2 right? yes, AdLib here
mov ax, 1 ;set return value of AX=1
jmp short eop
noAdLib:
mov ax, 0 ;set return value of AX=0
eop:
pop dx ;restore DX
ret
endp
public detect_sb
detect_sb proc near
comment *
Purpose:
To detect whether a SoundBlaster-compatible is installed
Entry:
DS:DI-> pointer to word memory location to record SoundBlaster
base port address to
Exit:
AX=0, if no SoundBlaster
AX=1, if SoundBlaster present
DS:DI-> returns last possible SB port tested
*
comment *
Start scanning for a SoundBlaster base port on every PC
port from 210h to 260h, in increments of 10h.
*
.data
sbflag db 0 ;indicates how many port tests passed
sbport dw 210h ;i/o port where SB is located
.code
push dx ;save DX before tests begin
mov dx, 210h ;first port to check
mov [di], dx ;save to passed memory location
push cx ;save CX, we'll be using it to loop
mov cx, 5 ;loop five times, test ports 210h-260h
chkports:
push cx
mov cx, 200h
add dx, 0Ch
chkport1:
in al, dx
and al, 80h
cmp al, 0
je short foundport1
loop chkport1
jmp short test2
foundport1:
inc sbflag ;first port in set found
test2:
pop cx
cmp [sbflag], 0
je short nextports ;no tests passed? go to next set
in al, dx ;small timing delay
mov al, 0d3h
out dx, al
push cx
mov cx, 1000h
donothing:
loop donothing ;large timing delay
pop cx
mov dx, [di]
add dx, 6
mov al, 1
out dx, al
rept 4
in al, dx ;timing delay
endm
mov al, 0
out dx, al
mov dx, [di]
add dx, 0Eh
push cx
mov cx, 200h
chkport2:
in al, dx
test al, 80h
je short foundport2
loop chkport2
jmp short noport2
foundport2:
inc sbflag ;found second port in series
noport2:
pop cx
cmp [sbflag], 2
jb nextports ;go to next set of ports
mov dx, [di]
add dx, 0Ah
in al, dx
cmp al, 0AAh
jne nextports
inc sbflag ;found third port in series
mov ax, 1 ;found SB, return AX=1
jmp yes_sb
nextports:
add word ptr [di], 10h
mov dx, [di]
if ($-chkports) lt 128
loop chkports
else
dec cx
cmp cx, 0
je @a
jmp chkports
@a:
endif
mov ax, 0 ;found no SB, return AX=0
yes_sb:
pop cx
pop dx
ret
endp
END