Subversion Repositories Kolibri OS

Rev

Rev 5057 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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