Subversion Repositories Kolibri OS

Rev

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

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