From bdd8453ba4c9de7db892e754c2bf14543d28f2e9 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 9 Aug 2008 17:09:47 +0000 Subject: [PATCH] from Nable: SB16 MASTERVOLUME git-svn-id: svn://kolibrios.org@850 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/drivers/sb16/CONFIG.INC | 27 ++++--- kernel/trunk/drivers/sb16/SB16.INC | 70 +++++++++++++++-- kernel/trunk/drivers/sb16/sb16.asm | 110 +++++++++++++++------------ kernel/trunk/drivers/uart.asm | 4 + 4 files changed, 148 insertions(+), 63 deletions(-) diff --git a/kernel/trunk/drivers/sb16/CONFIG.INC b/kernel/trunk/drivers/sb16/CONFIG.INC index d39356ed69..026915d943 100644 --- a/kernel/trunk/drivers/sb16/CONFIG.INC +++ b/kernel/trunk/drivers/sb16/CONFIG.INC @@ -1,6 +1,6 @@ ;flags------------------------------------------------------------ -DEBUG equ 1 ;show messages at debug board -use_cli_sti equ 1 ;driver come more stable (theoretically) +DEBUG equ 1 ;show messages at debug board +use_cli_sti equ 1 ;driver become more stable (theoretically) ;constants-------------------------------------------------------- API_VERSION equ 0 ;debug @@ -10,20 +10,29 @@ new_app_base equ 0x0 PROC_BASE equ (OS_BASE+0x080000) SB16Buffer equ (OS_BASE+0x2A0000) SB16_Status equ (OS_BASE+0x2B0000) -DMAPage equ ((SB16Buffer-OS_BASE) shr 16) +DMAPage equ ((SB16Buffer-OS_BASE) shr 16) SB16Buffer0 equ SB16Buffer SB16Buffer1 equ (SB16Buffer+16384) SB16Buffer2 equ (SB16Buffer+(2*16384)) SB16Buffer3 equ (SB16Buffer+(3*16384)) -sb_irq_num equ 5 -sb_dma_num equ 5 -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 +sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect +sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect +small_buffer equ 32768 +full_buffer equ 65536 +sb_buffer_size equ full_buffer + +__supported_buffer_sizes fix + +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))) SRV_GETVERSION equ 0 diff --git a/kernel/trunk/drivers/sb16/SB16.INC b/kernel/trunk/drivers/sb16/SB16.INC index f48db82cac..40f03ba4e2 100644 --- a/kernel/trunk/drivers/sb16/SB16.INC +++ b/kernel/trunk/drivers/sb16/SB16.INC @@ -43,7 +43,7 @@ end if mov al,((sb_buffer_size-1) and 0xff) out dx,al - mov al,((sb_buffer_size-1) shr 8) ;it is the same + mov al,((sb_buffer_size-1) shr 8) ;it is the same out dx,al mov eax,ebx ;unmask DMA channel @@ -129,8 +129,8 @@ proc sb_play mov edx,[sb_base_port] add dl,0xC 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 ;@@: ;out the low byte... ; in al,dx @@ -162,7 +162,7 @@ proc sb_play ; || |||| ; ---------reserved ;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) shr 8) ;wSize.HighByte ret @@ -192,6 +192,7 @@ end if out dx,al ret endp + ;------------------------------------------------------------------------------- ; 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 (sb_out_rate shr 8) ;first high byte (MSB) 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 ; out dx,al ;select this register of the mixer ; mov ecx,6 ;wait for the chip @@ -236,4 +238,60 @@ proc sb_setup ; in al,dx ; loop @b ret -endp \ No newline at end of file +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 +;------------------------------------------------------------------------------- diff --git a/kernel/trunk/drivers/sb16/sb16.asm b/kernel/trunk/drivers/sb16/sb16.asm index 85fc081c6c..91674bcdbf 100644 --- a/kernel/trunk/drivers/sb16/sb16.asm +++ b/kernel/trunk/drivers/sb16/sb16.asm @@ -37,7 +37,6 @@ include 'sb16.inc' ;------------------------------------------------------------------------------- proc START stdcall, state:dword - cmp [state], 1 jne .stop .entry: @@ -53,15 +52,16 @@ end if if DEBUG movzx eax,al ;major version + mov esi,sb_DSP_description dec eax jz .sb_say_about_found_dsp - mov dword[sb_DSP_description],'2.x ' + mov dword[esi],'2.x ' dec eax jz .sb_say_about_found_dsp - mov dword[sb_DSP_description],'Pro ' + mov dword[esi],'Pro ' dec eax jz .sb_say_about_found_dsp - mov dword[sb_DSP_description],'16 ' + mov dword[esi],'16 ' .sb_say_about_found_dsp: mov esi,msgDSPFound call SysMsgBoardStr @@ -69,7 +69,7 @@ end if xor eax,eax mov ebx,[sb_base_port] lea ecx,[ebx+0xF] - call ReservePortArea ;these ports must be mine! + call ReservePortArea ;these ports must be my! if DEBUG dec eax jnz @f @@ -147,6 +147,8 @@ end if call sb_set_dma ;is it really needed here? Paranoia. call sb_play + xor eax,eax ;set maximum volume + call sb_set_master_vol xor eax,eax ret ;@@: ;all this commented stuff in service proc @@ -172,29 +174,34 @@ end if if DEBUG call SysMsgBoardNum end if + xor eax,eax ret @@: -; cmp eax,DEV_SET_MASTERVOL -; jne @F -;if DEBUG -; mov esi,msgSetVol -; call SysMsgBoardStr -;end if -; mov eax,[edi+input] -; mov eax,[eax] -; mov [sb_master_vol],eax -; ret -;@@: -; cmp eax,DEV_GET_MASTERVOL -; jne @F -;if DEBUG -; mov esi,msgGetVol -; call SysMsgBoardStr -;end if -; mov eax,[edi+output] -; mov edx,[sb_master_vol] -; mov [eax],edx -; ret + cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock + jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it. + ;It doesn't use it _in current version_ - but in the future... + +if DEBUG + mov esi,msgSetVol + call SysMsgBoardStr +end if + mov eax,[edi+input] + mov eax,[eax] + call sb_set_master_vol + xor eax,eax + ret +@@: + cmp eax,DEV_GET_MASTERVOL + jne @F +if DEBUG + mov esi,msgGetVol + call SysMsgBoardStr +end if + mov eax,[edi+output] + mov edx,[sb_master_vol] + mov [eax],edx + xor eax,eax + ret .fail: or eax, -1 @@ -222,18 +229,22 @@ pre_fill_data: test eax,eax jns .fill_second_half - stdcall [callback],SB16Buffer0 ;for 32k buffer -; stdcall [callback],SB16Buffer0 ;for 64k buffer -; stdcall [callback],SB16Buffer1 ;for 64k buffer - +if sb_buffer_size eq small_buffer + stdcall [callback],SB16Buffer0 ;for 32k buffer +else if sb_buffer_size eq full_buffer + stdcall [callback],SB16Buffer0 ;for 64k buffer + stdcall [callback],SB16Buffer1 ;for 64k buffer +end if xor eax,eax ret .fill_second_half: - stdcall [callback],SB16Buffer1 ;for 32k buffer -; stdcall [callback],SB16Buffer2 ;for 64k buffer -; stdcall [callback],SB16Buffer3 ;for 64k buffer - +if sb_buffer_size eq small_buffer + stdcall [callback],SB16Buffer1 ;for 32k buffer +else if sb_buffer_size eq full_buffer + stdcall [callback],SB16Buffer2 ;for 64k buffer + stdcall [callback],SB16Buffer3 ;for 64k buffer +end if xor eax,eax ret endp @@ -291,6 +302,7 @@ end if div dl ror eax,16 xor ah,ah + mov [sb_DSP_version_int],eax ;for internal usage if DEBUG add [sb_DSP_version],eax end if @@ -302,7 +314,7 @@ end if endp ;------------------------------------------------------------------------------- if DEBUG -proc SysMsgBoardNum +proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi mov ebx,eax mov ecx,8 mov esi,(number_to_out+1) @@ -323,17 +335,10 @@ proc SysMsgBoardNum endp end if ;all initialized data place here - align 4 version dd (5 shl 16) or (API_VERSION and 0xFFFF) -sb_base_port: dd 200h - -;pTempBuf dd 0 - -callback dd 0 - -int_flip_flop dd 0 +sb_base_port: dd 200h ;don't ask me why - see the code&docs sound_dma dd sb_dma_num @@ -341,8 +346,6 @@ sound_dma dd sb_dma_num ;plugging the first DMA controler to the second 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 if DEBUG @@ -360,8 +363,8 @@ msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0') db ' as hardcoded',13,10,0 msgErrRsrvPorts db 'failed to reserve needed ports.',13,10 db 'Driver may work unstable',13,10,0 -;msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0 -;msgGetVol db 'DEV_GET_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 msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0 ;------------------------------------------------------------------------------- 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 ;------------------------------------------------------------------------------- end if -;section '.data' data readable writable align 16 + +section '.data' data readable writable align 16 ;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 diff --git a/kernel/trunk/drivers/uart.asm b/kernel/trunk/drivers/uart.asm index 8502b4f589..a445a74a8e 100644 --- a/kernel/trunk/drivers/uart.asm +++ b/kernel/trunk/drivers/uart.asm @@ -7,9 +7,13 @@ format MS COFF +DEBUG equ 1 + include 'proc32.inc' include 'imports.inc' + + API_VERSION equ 0 UART_VERSION equ API_VERSION