Subversion Repositories Kolibri OS

Rev

Rev 1735 | 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.            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: dd 200h ;don't ask me why - see the code&docs
  348.  
  349. sound_dma     dd sb_dma_num
  350.  
  351. ;note that 4th DMA channel doesn't exist, it is used for cascade
  352. ;plugging the first DMA controler to the second
  353. dma_table     db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
  354.  
  355. my_service    db 'SOUND',0  ;max 16 chars include zero
  356.  
  357. if DEBUG
  358. number_to_out db '0x00000000',13,10,0
  359.  
  360. msgInit       db 'detecting hardware...',13,10,0
  361. msgExit       db 'exiting... May be some problems found?',13,10,0
  362. msgPlay       db 'start play',13,10,0
  363. ;msgStop       db 'stop play',13,10,0
  364. msgCallback   db 'set_callback received from the mixer!',13,10
  365.               db 'callback handler is: ',0
  366. msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
  367.               db 'owner',39,'s handler: ',0
  368. msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
  369.               db ' as hardcoded',13,10,0
  370. msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
  371.               db 'Driver may work unstable',13,10,0
  372. msgSetVol     db 'DEV_SET_MASTERVOL call came',13,10,0
  373. msgGetVol     db 'DEV_GET_MASTERVOL call came',13,10,0
  374. msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
  375. ;-------------------------------------------------------------------------------
  376. msgDSPFound   db 'DSP found at port 2'
  377. label port_second_digit_num dword at $
  378.               db '00h',13,10,'DSP version '
  379. sb_DSP_version: db '0.00 - SB'
  380. sb_DSP_description: db 32,32,32,32,13,10,0
  381. ;-------------------------------------------------------------------------------
  382. end if
  383.  
  384. section '.data' data readable writable align 16
  385. ;all uninitialized data place here
  386.  
  387. ;pTempBuf          rd 1
  388.  
  389. callback           rd 1
  390.  
  391. int_flip_flop      rd 1
  392.  
  393. sb_master_vol      rd 1
  394.  
  395. sb_DSP_version_int rd 1
  396.