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------------------------------------------------------------
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 <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)))
SRV_GETVERSION equ 0

View File

@ -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
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
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

View File

@ -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