Subversion Repositories Kolibri OS

Rev

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

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