0,0 → 1,382 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
format PE DLL native 0.05 |
entry START |
|
include 'CONFIG.INC' |
|
section '.flat' code readable writable executable |
include '..\..\struct.inc' |
include '..\..\macros.inc' |
include '..\..\proc32.inc' |
include '..\..\peimport.inc' |
|
include 'SB16.INC' |
|
;------------------------------------------------------------------------------- |
proc START c uses ebx esi edi, state:dword, cmdline:dword |
cmp [state], 1 |
jne .stop |
.entry: |
|
if DEBUG |
mov esi, msgInit |
invoke SysMsgBoardStr |
end if |
|
call detect ;returns DSP version or zero if |
test eax, eax ;SB card not found |
jz .exit |
|
if DEBUG |
movzx eax, al ;major version |
mov esi, sb_DSP_description |
dec eax |
jz .sb_say_about_found_dsp |
mov dword[esi], '2.x ' |
dec eax |
jz .sb_say_about_found_dsp |
mov dword[esi], 'Pro ' |
dec eax |
jz .sb_say_about_found_dsp |
mov dword[esi], '16 ' |
.sb_say_about_found_dsp: |
mov esi, msgDSPFound |
invoke SysMsgBoardStr |
end if |
|
xor ebx, ebx |
mov ecx, [sb_base_port] |
lea edx, [ecx+0xF] |
invoke ReservePortArea ;these ports must be mine ! |
|
dec eax |
jnz @f |
|
if DEBUG |
mov esi, msgErrRsrvPorts |
invoke SysMsgBoardStr |
end if |
jmp .exit |
|
@@: |
invoke AllocDMA24, sb_buffer_size |
test eax, eax |
jz .exit |
mov [SB16Buffer], eax |
|
call sb_setup ;clock it, etc |
|
invoke AttachIntHandler, sb_irq_num, sb_irq, 0 |
|
if DEBUG |
test eax, eax |
jnz @f |
|
mov esi, msgErrAtchIRQ |
invoke SysMsgBoardStr |
|
; stdcall GetIntHandler, sb_irq_num |
; call SysMsgBoardNum |
|
jmp .stop |
@@: |
mov esi, msgSucAtchIRQ |
invoke SysMsgBoardStr |
end if |
invoke RegService, my_service, service_proc |
ret |
.stop: |
call sb_reset |
.exit: |
|
if DEBUG |
mov esi, msgExit |
invoke SysMsgBoardStr |
end if |
|
xor eax, eax |
ret |
endp |
;------------------------------------------------------------------------------- |
|
proc service_proc stdcall uses ebx esi edi, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+IOCTL.io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
|
mov eax, [edi+IOCTL.output] |
cmp [edi+IOCTL.out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @f |
if DEBUG |
mov esi, msgPlay |
invoke SysMsgBoardStr |
end if |
call sb_stop ;to play smth new we must stop smth old |
|
call pre_fill_data ;fill first and second half of the buffer |
call pre_fill_data ; |
|
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 |
; cmp eax,DEV_STOP ;is never used. Mixer do this virtually, |
; jne @f ;e.g. instead of stopping driver it |
;if DEBUG ;outputs silence |
; mov esi,msgStop |
; call SysMsgBoardStr |
;end if |
; call sb_stop |
; xor eax,eax |
; ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @f |
if DEBUG |
mov esi, msgCallback |
invoke SysMsgBoardStr |
end if |
mov edi, [edi+IOCTL.input] |
mov eax, [edi] |
mov [callback], eax |
if DEBUG |
call SysMsgBoardNum |
end if |
xor eax, eax |
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 |
invoke SysMsgBoardStr |
end if |
mov eax, [edi+IOCTL.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 |
invoke SysMsgBoardStr |
end if |
mov eax, [edi+IOCTL.output] |
mov edx, [sb_master_vol] |
mov [eax], edx |
xor eax, eax |
ret |
|
.fail: |
or eax, -1 |
ret |
endp |
|
;------------------------------------------------------------------------------- |
proc sb_irq |
mov edx, [sb_base_port];tell the DSP that we have processed IRQ |
add dl, 0xF ;0xF for 16 bit sound, 0xE for 8 bit sound |
in al, dx ;for non-stop sound |
|
pre_fill_data: |
mov eax, int_flip_flop |
not dword[eax] |
mov eax, [eax] |
test eax, eax |
jns .fill_second_half |
|
if sb_buffer_size eq small_buffer |
mov eax, [SB16Buffer] |
stdcall [callback], eax ;for 32k buffer |
else if sb_buffer_size eq full_buffer |
mov eax, [SB16Buffer] |
push eax |
stdcall [callback], eax ;for 64k buffer |
pop eax |
add eax, 16384 |
stdcall [callback], eax ;for 64k buffer |
end if |
xor eax, eax |
not eax |
ret |
|
.fill_second_half: |
if sb_buffer_size eq small_buffer |
mov eax, [SB16Buffer] |
add eax, 16384 |
stdcall [callback], eax ;for 32k buffer |
else if sb_buffer_size eq full_buffer |
mov eax, [SB16Buffer] |
add eax, 32768 |
push eax |
stdcall [callback], eax ;for 64k buffer |
pop eax |
add eax, 16384 |
stdcall [callback], eax ;for 64k buffer |
end if |
xor eax, eax |
not eax |
ret |
endp |
;------------------------------------------------------------------------------- |
align 4 |
proc detect |
.sb_detect_next_port: |
if DEBUG |
inc dword[port_second_digit_num] |
end if |
mov edx, sb_base_port |
add byte[edx], 10h |
cmp byte[edx], 80h |
jbe .sb_try_to_detect_at_specified_port |
;error - no SB card detected |
.sb_not_found_err: |
xor eax, eax |
ret |
|
.sb_try_to_detect_at_specified_port: |
call sb_reset |
add dl, 8 |
mov ecx, 100 |
.sb_check_port: |
in al, dx |
test al, al ;is DSP port ready to be read? |
jns .sb_port_not_ready |
|
sub dl, 4 |
in al, dx ;check for AAh response |
add dl, 4 |
cmp al, 0xAA |
jne .sb_port_not_ready |
.sb_card_found: |
and dl, 0xF0 |
add dl, 0xC |
sb_out 0xE1 ;get DSP version |
add dl, 2 |
@@: |
in al, dx |
test al, al ;is DSP port ready to be read? |
jns @b |
sub dl, 4 |
in al, dx ;get major version |
ror eax, 16 |
add dl, 4 |
@@: |
in al, dx |
test al, al ;is DSP port ready to be read? |
jns @b |
sub dl, 4 |
in al, dx ;get minor version |
xor edx, edx |
mov dl, 10 |
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 |
ret |
|
.sb_port_not_ready: |
loop .sb_check_port ;100 retries (~100 microsec.) |
jmp .sb_detect_next_port |
endp |
;------------------------------------------------------------------------------- |
if DEBUG |
proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi |
mov ebx, eax |
mov ecx, 8 |
mov esi, (number_to_out+1) |
.1: |
mov eax, ebx |
and eax, 0xF |
add al, '0' |
cmp al, (10+'0') |
jb @f |
add al, ('A'-'0'-10) |
@@: |
mov [esi+ecx], al |
shr ebx, 4 |
loop .1 |
dec esi |
invoke SysMsgBoardStr |
ret |
endp |
end if |
;all initialized data place here |
align 4 |
|
sb_base_port: |
dd 200h ;don't ask me why - see the code&docs |
|
sound_dma dd sb_dma_num |
|
;note that 4th DMA channel doesn't exist, it is used for cascade |
;plugging the first DMA controler to the second |
dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A |
|
my_service db 'SOUND',0 ;max 16 chars include zero |
|
if DEBUG |
number_to_out db '0x00000000',13,10,0 |
|
msgInit db 'detecting hardware...',13,10,0 |
msgExit db 'exiting... May be some problems found?',13,10,0 |
msgPlay db 'start play',13,10,0 |
;msgStop db 'stop play',13,10,0 |
msgCallback db 'set_callback received from the mixer!',13,10 |
db 'callback handler is: ',0 |
msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10 |
db 'owner',39,'s handler: ',0 |
msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0') |
db ' as hardcoded',13,10,0 |
msgErrRsrvPorts db 'failed to reserve needed ports.',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' |
label port_second_digit_num dword at $ |
db '00h',13,10,'DSP version ' |
sb_DSP_version: |
db '0.00 - SB' |
sb_DSP_description: |
db 32,32,32,32,13,10,0 |
;------------------------------------------------------------------------------- |
end if |
|
align 4 |
data fixups |
end data |
|
align 4 |
SB16Buffer rd 1 |
|
callback rd 1 |
|
int_flip_flop rd 1 |
|
sb_master_vol rd 1 |
|
sb_DSP_version_int rd 1 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |