Subversion Repositories Kolibri OS

Rev

Rev 802 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. format MS COFF
  9.  
  10. include 'config.inc'
  11.  
  12. ;structs----------------------------------------------------------
  13. struc IOCTL
  14. {  .handle      dd ?
  15.    .io_code     dd ?
  16.    .input       dd ?
  17.    .inp_size    dd ?
  18.    .output      dd ?
  19.    .out_size    dd ?
  20. }
  21.  
  22. virtual at 0
  23.   IOCTL IOCTL
  24. end virtual
  25.  
  26. ;something--------------------------------------------------------
  27. public START
  28. public service_proc
  29. public version
  30.  
  31. include '..\proc32.inc'
  32. include '..\imports.inc'
  33.  
  34. section '.flat' code readable align 16
  35.  
  36. include 'sb16.inc'
  37.  
  38. ;-------------------------------------------------------------------------------
  39. proc START stdcall, state:dword
  40.            cmp  [state], 1
  41.            jne  .stop
  42. .entry:
  43.  
  44. if DEBUG
  45.            mov  esi, msgInit
  46.            call SysMsgBoardStr
  47. end if
  48.  
  49.            call detect           ;returns DSP version or zero if
  50.            test eax,eax          ;SB card not found
  51.            jz   .exit
  52.  
  53. if DEBUG
  54.            movzx eax,al          ;major version
  55.            mov esi,sb_DSP_description
  56.            dec eax
  57.            jz  .sb_say_about_found_dsp
  58.            mov dword[esi],'2.x '
  59.            dec eax
  60.            jz  .sb_say_about_found_dsp
  61.            mov dword[esi],'Pro '
  62.            dec eax
  63.            jz  .sb_say_about_found_dsp
  64.            mov dword[esi],'16  '
  65. .sb_say_about_found_dsp:
  66.            mov esi,msgDSPFound
  67.            call SysMsgBoardStr
  68. end if
  69.            xor  eax,eax
  70.            mov  ebx,[sb_base_port]
  71.            lea  ecx,[ebx+0xF]
  72.            call ReservePortArea  ;these ports must be my!
  73. if DEBUG
  74.            dec  eax
  75.            jnz  @f
  76.            mov  esi,msgErrRsrvPorts
  77.            call SysMsgBoardStr
  78. @@:
  79. end if
  80.  
  81.            call sb_setup         ;clock it, etc
  82.  
  83.            stdcall AttachIntHandler, sb_irq_num, sb_irq, 0
  84.  
  85. if DEBUG
  86.            test eax,eax
  87.            jnz  @f
  88.  
  89.            mov  esi,msgErrAtchIRQ
  90.            call SysMsgBoardStr
  91.  
  92.            stdcall GetIntHandler, sb_irq_num
  93.            call SysMsgBoardNum
  94.  
  95.            jmp  .stop
  96. @@:
  97.            mov  esi,msgSucAtchIRQ
  98.            call SysMsgBoardStr
  99. end if
  100.            stdcall RegService, my_service, service_proc
  101.            ret
  102. .stop:
  103.            call sb_reset
  104. .exit:
  105.  
  106. if DEBUG
  107.            mov esi,msgExit
  108.            call SysMsgBoardStr
  109. end if
  110.  
  111.            xor  eax, eax
  112.            ret
  113. endp
  114. ;-------------------------------------------------------------------------------
  115.  
  116. handle     equ  IOCTL.handle
  117. io_code    equ  IOCTL.io_code
  118. input      equ  IOCTL.input
  119. inp_size   equ  IOCTL.inp_size
  120. output     equ  IOCTL.output
  121. out_size   equ  IOCTL.out_size
  122.  
  123. align 4
  124. proc service_proc stdcall, ioctl:dword
  125.            mov  edi,[ioctl]
  126.            mov  eax,[edi+io_code]
  127.            cmp  eax,SRV_GETVERSION
  128.            jne  @F
  129.  
  130.            mov  eax,[edi+output]
  131.            cmp  [edi+out_size],4
  132.            jne  .fail
  133.            mov  [eax],dword API_VERSION
  134.            xor  eax,eax
  135.            ret
  136. @@:
  137.            cmp  eax,DEV_PLAY
  138.            jne  @f
  139. if DEBUG
  140.            mov  esi,msgPlay
  141.            call SysMsgBoardStr
  142. end if
  143.            call sb_stop          ;to play smth new we must stop smth old
  144.  
  145.            call pre_fill_data    ;fill first and second half of the buffer
  146.            call pre_fill_data    ;
  147.  
  148.            call sb_set_dma       ;is it really needed here? Paranoia.
  149.            call sb_play
  150.            xor  eax,eax           ;set maximum volume
  151.            call sb_set_master_vol
  152.            xor  eax,eax
  153.            ret
  154. ;@@:                             ;all this commented stuff in service proc
  155. ;           cmp  eax,DEV_STOP    ;is never used. Mixer do this virtually,
  156. ;           jne  @f              ;e.g. instead of stopping driver it
  157. ;if DEBUG                        ;outputs silence
  158. ;           mov  esi,msgStop
  159. ;           call SysMsgBoardStr
  160. ;end if
  161. ;           call sb_stop
  162. ;           xor  eax,eax
  163. ;           ret
  164. @@:
  165.            cmp  eax,DEV_CALLBACK
  166.            jne  @f
  167. if DEBUG
  168.            mov  esi,msgCallback
  169.            call SysMsgBoardStr
  170. end if
  171.            mov  edi,[edi+input]
  172.            mov  eax,[edi]
  173.            mov  [callback],eax
  174. if DEBUG
  175.            call SysMsgBoardNum
  176. end if
  177.            xor  eax,eax
  178.            ret
  179. @@:
  180.            cmp  eax,DEV_SET_MASTERVOL ;Serge asked me to unlock
  181.            jne  @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it.
  182.            ;It doesn't use it _in current version_ - but in the future...
  183.  
  184. if DEBUG
  185.            mov  esi,msgSetVol
  186.            call SysMsgBoardStr
  187. end if
  188.            mov  eax,[edi+input]
  189.            mov  eax,[eax]
  190.            call sb_set_master_vol
  191.            xor  eax,eax
  192.            ret
  193. @@:
  194.            cmp  eax,DEV_GET_MASTERVOL
  195.            jne  @F
  196. if DEBUG
  197.            mov  esi,msgGetVol
  198.            call SysMsgBoardStr
  199. end if
  200.            mov  eax,[edi+output]
  201.            mov  edx,[sb_master_vol]
  202.            mov  [eax],edx
  203.            xor  eax,eax
  204.            ret
  205.  
  206. .fail:
  207.            or eax, -1
  208.            ret
  209. endp
  210.  
  211. restore   handle
  212. restore   io_code
  213. restore   input
  214. restore   inp_size
  215. restore   output
  216. restore   out_size
  217.  
  218. ;-------------------------------------------------------------------------------
  219. align 4
  220. proc sb_irq
  221.            mov  edx,[sb_base_port] ;tell the DSP that we have processed IRQ
  222.            add  dl,0xF             ;0xF for 16 bit sound, 0xE for 8 bit sound
  223.            in   al,dx              ;for non-stop sound
  224.  
  225. pre_fill_data:
  226.            mov  eax,int_flip_flop
  227.            not  dword[eax]
  228.            mov  eax,[eax]
  229.            test eax,eax
  230.            jns  .fill_second_half
  231.  
  232. if sb_buffer_size eq small_buffer
  233.            stdcall [callback],SB16Buffer0 ;for 32k buffer
  234. else if sb_buffer_size eq full_buffer
  235.            stdcall [callback],SB16Buffer0 ;for 64k buffer
  236.            stdcall [callback],SB16Buffer1 ;for 64k buffer
  237. end if
  238.            xor  eax,eax
  239.            ret
  240.  
  241. .fill_second_half:
  242. if sb_buffer_size eq small_buffer
  243.            stdcall [callback],SB16Buffer1 ;for 32k buffer
  244. else if sb_buffer_size eq full_buffer
  245.            stdcall [callback],SB16Buffer2 ;for 64k buffer
  246.            stdcall [callback],SB16Buffer3 ;for 64k buffer
  247. end if
  248.            xor  eax,eax
  249.            ret
  250. endp
  251. ;-------------------------------------------------------------------------------
  252. align 4
  253. proc detect
  254. .sb_detect_next_port:
  255. if DEBUG
  256.            inc  dword[port_second_digit_num]
  257. end if
  258.            mov  edx,sb_base_port
  259.            add  byte[edx],10h
  260.            cmp  byte[edx],80h
  261.            jbe  .sb_try_to_detect_at_specified_port
  262. ;error - no SB card detected
  263. .sb_not_found_err:
  264.            xor  eax, eax
  265.            ret
  266.  
  267. .sb_try_to_detect_at_specified_port:
  268.            call sb_reset
  269.            add  dl,8
  270.            mov  ecx,100
  271. .sb_check_port:
  272.            in   al,dx
  273.            test al,al            ;is DSP port ready to be read?
  274.            jns  .sb_port_not_ready
  275.  
  276.            sub  dl,4
  277.            in   al,dx            ;check for AAh response
  278.            add  dl,4
  279.            cmp  al,0xAA
  280.            jne  .sb_port_not_ready
  281. .sb_card_found:
  282.            and  dl,0xF0
  283.            add  dl,0xC
  284.            sb_out 0xE1           ;get DSP version
  285.            add  dl,2
  286. @@:
  287.            in   al,dx
  288.            test al,al            ;is DSP port ready to be read?
  289.            jns  @b
  290.            sub  dl,4
  291.            in   al,dx            ;get major version
  292.            ror  eax,16
  293.            add  dl,4
  294. @@:
  295.            in   al,dx
  296.            test al,al            ;is DSP port ready to be read?
  297.            jns  @b
  298.            sub  dl,4
  299.            in   al,dx            ;get minor version
  300.            xor  edx,edx
  301.            mov  dl,10
  302.            div  dl
  303.            ror  eax,16
  304.            xor  ah,ah
  305.            mov  [sb_DSP_version_int],eax ;for internal usage
  306. if DEBUG
  307.            add  [sb_DSP_version],eax
  308. end if
  309.            ret
  310.  
  311. .sb_port_not_ready:
  312.            loop .sb_check_port   ;100 retries (~100 microsec.)
  313.            jmp  .sb_detect_next_port
  314. endp
  315. ;-------------------------------------------------------------------------------
  316. if DEBUG
  317. proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
  318.            mov  ebx,eax
  319.            mov  ecx,8
  320.            mov  esi,(number_to_out+1)
  321. .1:
  322.            mov  eax,ebx
  323.            and  eax,0xF
  324.            add  al,'0'
  325.            cmp  al,(10+'0')
  326.            jb   @f
  327.            add  al,('A'-'0'-10)
  328. @@:
  329.            mov  [esi+ecx],al
  330.            shr  ebx,4
  331.            loop .1
  332.            dec  esi
  333.            call SysMsgBoardStr
  334.            ret
  335. endp
  336. end if
  337. ;all initialized data place here
  338. align 4
  339. version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
  340.  
  341. sb_base_port: dd 200h ;don't ask me why - see the code&docs
  342.  
  343. sound_dma     dd sb_dma_num
  344.  
  345. ;note that 4th DMA channel doesn't exist, it is used for cascade
  346. ;plugging the first DMA controler to the second
  347. dma_table     db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
  348.  
  349. my_service    db 'SOUND',0  ;max 16 chars include zero
  350.  
  351. if DEBUG
  352. number_to_out db '0x00000000',13,10,0
  353.  
  354. msgInit       db 'detecting hardware...',13,10,0
  355. msgExit       db 'exiting... May be some problems found?',13,10,0
  356. msgPlay       db 'start play',13,10,0
  357. ;msgStop       db 'stop play',13,10,0
  358. msgCallback   db 'set_callback received from the mixer!',13,10
  359.               db 'callback handler is: ',0
  360. msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
  361.               db 'owner',39,'s handler: ',0
  362. msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
  363.               db ' as hardcoded',13,10,0
  364. msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
  365.               db 'Driver may work unstable',13,10,0
  366. msgSetVol     db 'DEV_SET_MASTERVOL call came',13,10,0
  367. msgGetVol     db 'DEV_GET_MASTERVOL call came',13,10,0
  368. msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
  369. ;-------------------------------------------------------------------------------
  370. msgDSPFound   db 'DSP found at port 2'
  371. label port_second_digit_num dword at $
  372.               db '00h',13,10,'DSP version '
  373. sb_DSP_version: db '0.00 - SB'
  374. sb_DSP_description: db 32,32,32,32,13,10,0
  375. ;-------------------------------------------------------------------------------
  376. end if
  377.  
  378. section '.data' data readable writable align 16
  379. ;all uninitialized data place here
  380.  
  381. ;pTempBuf          rd 1
  382.  
  383. callback           rd 1
  384.  
  385. int_flip_flop      rd 1
  386.  
  387. sb_master_vol      rd 1
  388.  
  389. sb_DSP_version_int rd 1
  390.