from Nable: SB16 MASTERVOLUME

git-svn-id: svn://kolibrios.org@850 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-08-09 17:09:47 +00:00
parent c6d4df748c
commit bdd8453ba4
4 changed files with 148 additions and 63 deletions

View File

@ -1,6 +1,6 @@
;flags------------------------------------------------------------ ;flags------------------------------------------------------------
DEBUG equ 1 ;show messages at debug board DEBUG equ 1 ;show messages at debug board
use_cli_sti equ 1 ;driver come more stable (theoretically) use_cli_sti equ 1 ;driver become more stable (theoretically)
;constants-------------------------------------------------------- ;constants--------------------------------------------------------
API_VERSION equ 0 ;debug API_VERSION equ 0 ;debug
@ -17,13 +17,22 @@ SB16Buffer1 equ (SB16Buffer+16384)
SB16Buffer2 equ (SB16Buffer+(2*16384)) SB16Buffer2 equ (SB16Buffer+(2*16384))
SB16Buffer3 equ (SB16Buffer+(3*16384)) SB16Buffer3 equ (SB16Buffer+(3*16384))
sb_irq_num equ 5 sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect
sb_dma_num equ 5 sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect
sb_buffer_size equ 32768 ;really it needs code modifications to change
;buffer size
sb_out_rate equ 44100
;time constant for cards older than SB16
small_buffer equ 32768
full_buffer equ 65536
sb_buffer_size equ full_buffer
__supported_buffer_sizes fix <small_buffer, full_buffer>
if ~(sb_buffer_size in __supported_buffer_sizes)
display 13,10,'unsupported buffer size was selected, check config.inc',13,10
stop
end if
sb_out_rate equ 48000
;time constant for cards older than SB16
sb_tc equ (256-(1000000/(sb_out_rate*2))) sb_tc equ (256-(1000000/(sb_out_rate*2)))
SRV_GETVERSION equ 0 SRV_GETVERSION equ 0

View File

@ -129,8 +129,8 @@ proc sb_play
mov edx,[sb_base_port] mov edx,[sb_base_port]
add dl,0xC add dl,0xC
sb_out 0xD1 ;turn speaker on sb_out 0xD1 ;turn speaker on
; sb_out 0x48 ;set DSP transfer size ;for older cards ; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported
; ;in this version
; mov ax,32767 ;(64k)/2-1 ; mov ax,32767 ;(64k)/2-1
;@@: ;out the low byte... ;@@: ;out the low byte...
; in al,dx ; in al,dx
@ -162,7 +162,7 @@ proc sb_play
; || |||| ; || ||||
; ---------reserved ; ---------reserved
;wSize is a number of 16bit samples less 1. For auto-init mode each half ;wSize is a number of 16bit samples less 1. For auto-init mode each half
;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 bytes ;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples
sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte
sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte
ret ret
@ -192,6 +192,7 @@ end if
out dx,al out dx,al
ret ret
endp endp
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
; set the rate for playing, enable stereo ; set the rate for playing, enable stereo
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
@ -204,7 +205,8 @@ proc sb_setup
sb_out 41h ;set sound rate, this can only SB16 sb_out 41h ;set sound rate, this can only SB16
sb_out (sb_out_rate shr 8) ;first high byte (MSB) sb_out (sb_out_rate shr 8) ;first high byte (MSB)
sb_out (sb_out_rate and 0xff) ;then low byte (LSB) sb_out (sb_out_rate and 0xff) ;then low byte (LSB)
; mov al,0xE
; mov al,0xE ;for older cards, not supported in this version
; sub dl,(0xC-4) ;talk to SB's mixer ; sub dl,(0xC-4) ;talk to SB's mixer
; out dx,al ;select this register of the mixer ; out dx,al ;select this register of the mixer
; mov ecx,6 ;wait for the chip ; mov ecx,6 ;wait for the chip
@ -237,3 +239,59 @@ proc sb_setup
; loop @b ; loop @b
ret ret
endp endp
;-------------------------------------------------------------------------------
; set master volume of SB mixer, note, not only SB16 but SBPro and older
; this is the first step to more full support for hardware
;-------------------------------------------------------------------------------
;in: eax in range [-10000;0] - master volume for _both_ channels
;note that x*3*17/2000 and x*3/2000*17 are not the same numbers,
;because we count in integers
proc sb_set_master_vol
mov [sb_master_vol],eax
add eax,10000 ;SB sound level rise from 0 to MAX_LEVEL
lea eax,[eax+eax*2] ;*3
mov ebx,2000 ;divisor
xor edx,edx
cmp byte[sb_DSP_version_int],4
jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because
;volume byte looks like that: 0xLR, where L - left
;channel volume, R - right, 0<=R,L<=15
div ebx
imul eax,17
mov edx,[sb_base_port]
push eax ;here for optimisation
add dl,4
mov al,0x22 ;write mixer register 0x22
out dx,al
in al,dx ;wait for the chip ;6
in al,dx ;wait for the chip ;5
in al,dx ;wait for the chip ;4
in al,dx ;wait for the chip ;3
in al,dx ;wait for the chip ;2
in al,dx ;wait for the chip ;1
pop eax ;go!
inc edx
out dx,al
ret
@@: ;SB16's MAX_LEVEL is 255
imul eax,17
div ebx
mov edx,[sb_base_port]
push eax ;here for optimisation
add dl,4
mov al,0x30 ;left speaker
out dx,al
pop eax ;<--+
inc edx ; \/
push eax ;here for optimisation
out dx,al ;write
dec edx
mov al,0x31 ;right speaker
out dx,al
pop eax
inc edx
out dx,al ;write
ret
endp
;-------------------------------------------------------------------------------

View File

@ -37,7 +37,6 @@ include 'sb16.inc'
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
proc START stdcall, state:dword proc START stdcall, state:dword
cmp [state], 1 cmp [state], 1
jne .stop jne .stop
.entry: .entry:
@ -53,15 +52,16 @@ end if
if DEBUG if DEBUG
movzx eax,al ;major version movzx eax,al ;major version
mov esi,sb_DSP_description
dec eax dec eax
jz .sb_say_about_found_dsp jz .sb_say_about_found_dsp
mov dword[sb_DSP_description],'2.x ' mov dword[esi],'2.x '
dec eax dec eax
jz .sb_say_about_found_dsp jz .sb_say_about_found_dsp
mov dword[sb_DSP_description],'Pro ' mov dword[esi],'Pro '
dec eax dec eax
jz .sb_say_about_found_dsp jz .sb_say_about_found_dsp
mov dword[sb_DSP_description],'16 ' mov dword[esi],'16 '
.sb_say_about_found_dsp: .sb_say_about_found_dsp:
mov esi,msgDSPFound mov esi,msgDSPFound
call SysMsgBoardStr call SysMsgBoardStr
@ -69,7 +69,7 @@ end if
xor eax,eax xor eax,eax
mov ebx,[sb_base_port] mov ebx,[sb_base_port]
lea ecx,[ebx+0xF] lea ecx,[ebx+0xF]
call ReservePortArea ;these ports must be mine! call ReservePortArea ;these ports must be my!
if DEBUG if DEBUG
dec eax dec eax
jnz @f jnz @f
@ -147,6 +147,8 @@ end if
call sb_set_dma ;is it really needed here? Paranoia. call sb_set_dma ;is it really needed here? Paranoia.
call sb_play call sb_play
xor eax,eax ;set maximum volume
call sb_set_master_vol
xor eax,eax xor eax,eax
ret ret
;@@: ;all this commented stuff in service proc ;@@: ;all this commented stuff in service proc
@ -172,29 +174,34 @@ end if
if DEBUG if DEBUG
call SysMsgBoardNum call SysMsgBoardNum
end if end if
xor eax,eax
ret ret
@@: @@:
; cmp eax,DEV_SET_MASTERVOL cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock
; jne @F jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it.
;if DEBUG ;It doesn't use it _in current version_ - but in the future...
; mov esi,msgSetVol
; call SysMsgBoardStr if DEBUG
;end if mov esi,msgSetVol
; mov eax,[edi+input] call SysMsgBoardStr
; mov eax,[eax] end if
; mov [sb_master_vol],eax mov eax,[edi+input]
; ret mov eax,[eax]
;@@: call sb_set_master_vol
; cmp eax,DEV_GET_MASTERVOL xor eax,eax
; jne @F ret
;if DEBUG @@:
; mov esi,msgGetVol cmp eax,DEV_GET_MASTERVOL
; call SysMsgBoardStr jne @F
;end if if DEBUG
; mov eax,[edi+output] mov esi,msgGetVol
; mov edx,[sb_master_vol] call SysMsgBoardStr
; mov [eax],edx end if
; ret mov eax,[edi+output]
mov edx,[sb_master_vol]
mov [eax],edx
xor eax,eax
ret
.fail: .fail:
or eax, -1 or eax, -1
@ -222,18 +229,22 @@ pre_fill_data:
test eax,eax test eax,eax
jns .fill_second_half jns .fill_second_half
if sb_buffer_size eq small_buffer
stdcall [callback],SB16Buffer0 ;for 32k buffer stdcall [callback],SB16Buffer0 ;for 32k buffer
; stdcall [callback],SB16Buffer0 ;for 64k buffer else if sb_buffer_size eq full_buffer
; stdcall [callback],SB16Buffer1 ;for 64k buffer stdcall [callback],SB16Buffer0 ;for 64k buffer
stdcall [callback],SB16Buffer1 ;for 64k buffer
end if
xor eax,eax xor eax,eax
ret ret
.fill_second_half: .fill_second_half:
if sb_buffer_size eq small_buffer
stdcall [callback],SB16Buffer1 ;for 32k buffer stdcall [callback],SB16Buffer1 ;for 32k buffer
; stdcall [callback],SB16Buffer2 ;for 64k buffer else if sb_buffer_size eq full_buffer
; stdcall [callback],SB16Buffer3 ;for 64k buffer stdcall [callback],SB16Buffer2 ;for 64k buffer
stdcall [callback],SB16Buffer3 ;for 64k buffer
end if
xor eax,eax xor eax,eax
ret ret
endp endp
@ -291,6 +302,7 @@ end if
div dl div dl
ror eax,16 ror eax,16
xor ah,ah xor ah,ah
mov [sb_DSP_version_int],eax ;for internal usage
if DEBUG if DEBUG
add [sb_DSP_version],eax add [sb_DSP_version],eax
end if end if
@ -302,7 +314,7 @@ end if
endp endp
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
if DEBUG if DEBUG
proc SysMsgBoardNum proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
mov ebx,eax mov ebx,eax
mov ecx,8 mov ecx,8
mov esi,(number_to_out+1) mov esi,(number_to_out+1)
@ -323,17 +335,10 @@ proc SysMsgBoardNum
endp endp
end if end if
;all initialized data place here ;all initialized data place here
align 4 align 4
version dd (5 shl 16) or (API_VERSION and 0xFFFF) version dd (5 shl 16) or (API_VERSION and 0xFFFF)
sb_base_port: dd 200h sb_base_port: dd 200h ;don't ask me why - see the code&docs
;pTempBuf dd 0
callback dd 0
int_flip_flop dd 0
sound_dma dd sb_dma_num sound_dma dd sb_dma_num
@ -341,8 +346,6 @@ sound_dma dd sb_dma_num
;plugging the first DMA controler to the second ;plugging the first DMA controler to the second
dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
;sb_master_vol dd 0
my_service db 'SOUND',0 ;max 16 chars include zero my_service db 'SOUND',0 ;max 16 chars include zero
if DEBUG if DEBUG
@ -360,8 +363,8 @@ msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
db ' as hardcoded',13,10,0 db ' as hardcoded',13,10,0
msgErrRsrvPorts db 'failed to reserve needed ports.',13,10 msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
db 'Driver may work unstable',13,10,0 db 'Driver may work unstable',13,10,0
;msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0 msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0
;msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0 msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0
msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0 msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
msgDSPFound db 'DSP found at port 2' msgDSPFound db 'DSP found at port 2'
@ -371,5 +374,16 @@ sb_DSP_version: db '0.00 - SB'
sb_DSP_description: db 32,32,32,32,13,10,0 sb_DSP_description: db 32,32,32,32,13,10,0
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
end if end if
;section '.data' data readable writable align 16
section '.data' data readable writable align 16
;all uninitialized data place here ;all uninitialized data place here
;pTempBuf rd 1
callback rd 1
int_flip_flop rd 1
sb_master_vol rd 1
sb_DSP_version_int rd 1

View File

@ -7,9 +7,13 @@
format MS COFF format MS COFF
DEBUG equ 1
include 'proc32.inc' include 'proc32.inc'
include 'imports.inc' include 'imports.inc'
API_VERSION equ 0 API_VERSION equ 0
UART_VERSION equ API_VERSION UART_VERSION equ API_VERSION