home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega A/V
/
mega_av.zip
/
mega_av
/
SOUNDUTL
/
SB_OSC.ZIP
/
OSC104.ASM
next >
Wrap
Assembly Source File
|
1992-01-22
|
16KB
|
503 lines
;definable options when compiling :
;
;/dMAX - Include Maximum Volume Indicator.
;/dVOL - Volume bar
;/dDET - Determine base-address yourself.
;/dOVER - Add base-address override function command line option /b:2
;
;if VOL is not defined, defining MAX will have no effect whatsoever.
;
;
;
;Osclilloscoop 1.04
;
;by : Ernst Teuling.
;
;Works for my sound blaster (base adress = 220h)
;you can change adresses below to suit your sb.
;
;Version 1.00 : Full screen osc.
;Version 1.01 : Use a window, show volume below.
;Version 1.02 : Use 2 colors in volume bar, also made changing colors easy.
; Also added, a window around volume bar
;Version 1.03 : Added a line which keeps max. volume for some time.
;Version 1.04 : Added automatic base-adress detection
;
;
;Note that this program doesn't reset the soundblaster, so some things might
;react strange if you've run this.
;
ifndef DET
BPORT = 220H ;Base Port address
XPORT = 226H ;Reset port address
WPORT = 22CH ;Write port address
RPORT = 22AH ;Read port address
APORT = 22EH ;Data Available port address
endif ;DET
READY = 0AAH
Bordercolor =1 ;Window border
OscColor =15 ;Oscilloscope
ifdef VOL
VolumeColor1=2 ;First part of volume bar
VolumeColor2=4 ;Second part of volume bar
ifdef MAX
MaxColor =15 ;Max. Volume indicator.
endif ;MAX
endif ;VOL
.model small
.stack 100h
.data
buffer db 320 dup(0)
text db 'Oscilloscope 1.04',13,10
db '=================',13,10,10
db 'Compiled options : - Oscilloscope Window',13,10
ifdef VOL
db ' - Volume Bar',13,10
ifdef MAX
db ' - Max. Volume Indicator',13,10
endif ;MAX
endif ;VOL
ifdef DET
db ' - Auto-detection of Sound Blaster',13,10
endif ;DET
ifdef OVER
db ' - Override base address switch',13,10
endif ;OVER
db 13,10,10
db 'This program is freeware.',13,10,10
db 'Written by : E.A.B.Teuling',13,10
db 'Compiled at : RUU, using TASM 2.5 (have not bought it myself yet).',13,10
db 'Reactions to : E.A.B.Teuling',13,10
db ' Langebaan 40',13,10
db ' 4206 VP, Gorinchem',13,10
db ' THE NETHERLANDS',13,10,10
db '$'
ifdef DET
noblaster db 'No SoundBlaster Found - Program aborted.',13,10,10,'$'
endif ;DET
b_port dw 0 ; Determined port adresses
x_port dw 0 ;
w_port dw 0 ;
r_port dw 0 ;
a_port dw 0 ;
ifdef VOL
ifdef MAX
maxvolume dw 0
keeptime dw 0
endif ;MAX
endif ;VOL
ifdef OVER
ComOptions db 'Command Line Switches are :',13,10
db '/b:x (where x is in range 1-6) indicates base address of SB.',13,10
db ' base address is found at : 2x0h'
db 13,10,10
db 'press any to continue.',13,10
db '$'
endif ;OVER
.code
ifdef OVER
call TestCommandLine ;Test for presence of commandLine
pushf
endif ;OVER
mov ax,@data
mov ds,ax ;Make DS point to Data Segment
mov ax,0a000h
mov es,ax ;Make ES point to Screen Segment
ifdef OVER
popf ;If user specified a base address
jc Overrided ;then skip testing part.
endif ;OVER
ifdef DET
call InitialiseSB ;Test for SB, and determine base address
jnc BlasterIsFound ;if found, then continue
mov ah,4ch ;else,....
int 21h ;Abort Program
BlasterIsFound:
endif ;DET
ifndef DET
mov word ptr [b_port],bport ;
mov word ptr [x_port],xport ;Initialise ports
mov word ptr [w_port],wport ;
mov word ptr [r_port],rport ;
mov word ptr [a_port],aport ;
endif ;not DET
ifdef OVER
overrided:
endif ;OVER
mov ax,13h
int 10h ;Change to mode 13h, MCGA 256 colors.
call DrawBorder ;Draw Window for the oscilloscope.
xor si,si
inc si
ifdef VOL
xor cx,cx ;Blank Volume bar
endif ;VOL
oncemore:
ifdef VOL
push cx
endif ;VOL
push si
mov al,20h
mov dx,[ds:w_port]
out dx,al ;Tell SoundBlaster you wanna read a byte.
GetMyByte:
mov dx,[ds:a_port]
in al,dx
cmp al,127 ;Check if Sound Blaster wants to give you a byte.
je GetMyByte
mov dx,[ds:r_port]
in al,dx ;Read a byte from SB
pop si
ifdef VOL
pop cx
call Add2VolumeBar ;Adjust volume bar for this sound.
push cx
endif ;VOL
shr al,1 ;Divide by 2, for adjusting to Window size
push ax
mov al,[ds:si] ;Read buffer for pixel to black out
xor ah,ah
call Paint ;Black Out Previous line
pop ax
mov [ds:si],al
mov ah,OscColor
call Paint ;Draw current line
inc si
cmp si,319 ;Are we at end of window?
jne Verdergaan ;Nope, then just continue.
xor si,si ;else, initialise pointer
inc si
ifdef VOL
pop cx
mov ax,cx ;Calculate volume bar
mov cl,160
div cl
call DrawVolume ;Draw volume bar
xor cx,cx ;Reset Volume bar
push cx
endif ;VOL
Verdergaan:
ifdef VOL
pop cx
endif ;VOL
xor ax,ax
inc ah
int 16h ;Anyone pressed a key?????
jz oncemore ;If not, just go on play Oscilloscope
mov ax,3
int 10h ;Wipe screen and set VGA text mode. (80x25)
mov ah,9
mov dx,offset Text
int 21h ;Write compiled options on screen
xor ax,ax
int 16h ;Wipe keyboard buffer
mov ah,4ch
int 21h ;Leave this program and goto DOS (Bleahhh)
Paint Proc ;Paint a pixel in color AH
push si ;Make sure our pointer isn't trashed.
push ax ;Make sure color isn't forgotten
xor ah,ah
inc al
mov cx,320 ;Calculate offset in screen segment of line
mul cx ;to draw on.
mov di,ax
add di,si ;add for correct column.
pop ax ;Get color back from stack
mov [es:di],ah ;Draw!!
pop si
ret
Paint Endp
ifdef VOL
Add2VolumeBar Proc ;Add a byte to the volume bar
push ax ;Make sure the byte isn't forgotten, cause it's still needed.
cmp al,80h ;Calculate distance to no-sound
jb LowByte
sub al,80h
jmp AddToBar
LowByte:
push dx
mov dl,80h
sub dl,al
mov al,dl
pop dx
AddToBar:
xor ah,ah
add cx,ax ;Adjust volume bar (will be showed when at end
pop ax ;of window)
ret
Add2VolumeBar EndP
DrawVolume Proc ;Draw the Volume Bar
push si
ifdef MAX ;*********************
push ax
mov bx,[ds:MaxVolume]
cmp al,bl ;Is current volume harder then Max. Volume
jb DoUpdateTime ;if not, then update timer.
mov [ds:MaxVolume],ax ;if yes, then replace max. volume with current
xor bx,bx
mov [ds:KeepTime],bx ;and reset timer.
DoUpdateTime:
inc word ptr [ds:Keeptime] ;update timer
cmp word ptr [ds:KeepTime],30 ;are we waiting long enough?
jne DontDrawMaxBar ;not then don't update max. volume
mov word ptr [ds:Keeptime],0 ;reset timer
pop ax
push ax
mov [ds:MaxVolume],ax ;Update max. volume
DontDrawMaxBar:
pop ax
endif ;MAX ******************
mov di,54401 ;Offset in screen segment for start of volume bar
xor bx,bx
DrawingLoop:
xor cx,cx
cmp bl,al ;Is there need to draw a color?
ja NoColourChange ;nope, then don't draw a color.
mov cl,VolumeColor1
cmp bl,70
jb NoColourChange
mov cl,VolumeColor2
NoColourChange:
push bx
add bx,bx
mov byte ptr [es:di+bx],cl ;
mov byte ptr [es:di+bx+320],cl ;Draw the bar
mov byte ptr [es:di+bx+640],cl ;
mov byte ptr [es:di+bx+960],cl ;
mov byte ptr [es:di+bx+1],cl ;
mov byte ptr [es:di+bx+321],cl ;
mov byte ptr [es:di+bx+641],cl ;
mov byte ptr [es:di+bx+961],cl ;
pop bx
inc bx
cmp bx,128 ;Is complete bar drawn??
jne DrawingLoop ;if not, draw on.
ifdef MAX ;****************
call DrawMaxVolume
endif ;MAX ****************
pop si
ret
DrawVolume EndP
ifdef MAX ;****************
DrawMaxVolume Proc ;Draw Max. volume indicator.
push si
push bx
mov si,54401 ;Initialise pointer
mov bx,[ds:MaxVolume] ;Get position
xor bh,bh
cmp bl,127
jb NotToHard ;To hard for bar (won't happen too often, I hope)
mov bl,127 ;decrease volume to fit box.
NotToHard:
add si,bx
add si,bx
mov byte ptr [es:si],MaxColor ;
mov byte ptr [es:si+320],MaxColor ;Draw max. volume indicator.
mov byte ptr [es:si+640],MaxColor ;
mov byte ptr [es:si+960],MaxColor ;
pop bx
pop si
ret
DrawMaxVolume EndP
endif ;MAX ****************
endif ;VOL
DrawBorder Proc ;Draw the border for osc. window.
mov si,0
mov cl,BorderColor
TopLine:
mov byte ptr [es:si],cl ;Draw color 2
inc si
cmp si,320 ;Is complete top line drawn?
jne TopLine ;if not, continue the drawing process.
xor dx,dx
Sides:
mov byte ptr [es:si],cl ;Draw Side Line left
mov byte ptr [es:si+319],cl ;Draw Side Line Right
add si,320
inc dx
cmp dx,128 ;Are we ready drawing the sides?
jne Sides ;if not, just go on drawing.
xor dx,dx
BottomLine:
mov byte ptr [es:si],cl ;Draw a pixel of bottom line
inc si
inc dx
cmp dx,320 ;Is complete bottom line drawn?
jne BottomLine ;if not, draw on.
ifdef VOL
mov si,54080 ;Pointer to start of line 169
xor dx,dx
VolumeTop:
mov [es:si],cl ;Draw pixel of volume window
inc si
inc dx
cmp dx,258 ;Is topline ready
jne VolumeTop ;not, then draw on.
mov si,54400 ;Pointer to start of line 170.
mov [es:si],cl ;
mov [es:si+320],cl ;Draw left side of box
mov [es:si+640],cl ;
mov [es:si+960],cl ;
add si,257
mov [es:si],cl ;
mov [es:si+320],cl ;Draw right side of box
mov [es:si+640],cl ;
mov [es:si+960],cl ;
mov si,55680
xor dx,dx
VolumeBottom:
mov [es:si],cl ;Draw bottom
inc dx
inc si
cmp dx,258 ;Is bottom-line ready
jne VolumeBottom ;If not the draw on.
endif ;VOL
ret
drawBorder EndP
ifdef DET
InitialiseSB Proc ;Init. SB and determine port addresses
mov word ptr [b_port],210h
mov word ptr [x_port],216h
mov word ptr [w_port],21ch
mov word ptr [r_port],21ah
mov word ptr [a_port],21eh
NotYetFound:
mov dx,[ds:x_port]
mov al,1
out dx,al ;Send RESET
call delay ;Wait must be approx. 3 ms is you have
xor al,al ;a very fast computer you might need to
out dx,al ;change the DELAY function
xor cx,cx
PollingLoop:
mov dx,[ds:r_port] ;
in al,dx ;Test SoundBlaster
inc cx
cmp cx,100
ja FinishedPolling ;If tested 100 times stop testing.
cmp al,READY ;Did sound blaster react
jne PollingLoop ;If not, test again.
FinishedPolling:
cmp al,READY ;was there a reaction?
je FoundBlaster ;If yes, we've got him.
add word ptr [ds:b_port],10h ;
add word ptr [ds:x_port],10h ;
add word ptr [ds:w_port],10h ;Update port addresses for new try
add word ptr [ds:r_port],10h ;
add word ptr [ds:a_port],10h ;
cmp word ptr [ds:b_port],270h ;Is base port address to high?
jne NotYetFound ;if not, try polling again.
mov ah,9 ;if so, tell user there is no Sound
mov dx,offset NoBlaster ;blaster
int 21h
stc ;Inform program of failure
ret
FoundBlaster:
clc ;Inform program of succes
ret
InitialiseSB EndP
Delay Proc ;Delay
push ax
xor ax,ax
DelayLoop1:
inc ax
cmp ax,0
jne DelayLoop1
pop ax
ret
Delay EndP
endif ;DET
ifdef OVER
TestCommandLine Proc
mov bx,80h
mov al,[ds:bx] ;Get length of command line
cmp al,1
jna NoCommandLine ;if there is no Com. Line skip testing
xor cx,cx
mov cl,al
xor bx,bx
mov si,82h ;DS:SI points to command line
ReadComLine:
mov al,[ds:si]
inc si
inc bx
cmp al,2fh ;is character a /
je commando ;then action follows
cmp al,2dh ;is character a -
je commando ;then action follows
cmp bl,cl ;did we reach the end?
jbe ReadComLine ;if not, continue testing
NoCommandLine:
clc ;tell program, Don't skip test part
ret
commando:
mov al,[ds:si]
cmp al,3fh ;is command '?' then
je ExplainThings ;explain command switches
and al,0dfh ;make characters Upper case
cmp al,42h ;is character 'B'
jne ExplainThings ;if not, explain user the use of command switch.
mov al,[ds:si+2] ;get parameter
sub al,48 ;
cmp al,0 ;
je ExplainThings ;if not in valid range, explain
cmp al,7
jnb ExplainThings ;if not in valid range, explain
mov cl,4
shl al,cl
mov ah,2
push ax
mov ax,@data
mov ds,ax
pop ax
mov [ds:b_port],ax ;Set addresses
add ax,6
mov [ds:x_port],ax
add ax,4
mov [ds:r_port],ax
add ax,2
mov [ds:w_port],ax
add ax,2
mov [ds:a_port],ax
stc ;tell program, skip testing for SB
ret
ExplainThings:
mov ax,@data
mov ds,ax
mov ah,9
mov dx,offset ComOptions
int 21h ;display help text
xor ax,ax
int 16h ;wait for keypress
clc
ret
TestCommandLine EndP
endif ;OVER
END