Subversion Repositories Kolibri OS

Rev

Rev 850 | 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.            ret
  244.  
  245. .fill_second_half:
  246. if sb_buffer_size eq small_buffer
  247.            stdcall [callback],SB16Buffer1 ;for 32k buffer
  248. else if sb_buffer_size eq full_buffer
  249.            stdcall [callback],SB16Buffer2 ;for 64k buffer
  250.            stdcall [callback],SB16Buffer3 ;for 64k buffer
  251. end if
  252.            xor  eax,eax
  253.            ret
  254. endp
  255. ;-------------------------------------------------------------------------------
  256. align 4
  257. proc detect
  258. .sb_detect_next_port:
  259. if DEBUG
  260.            inc  dword[port_second_digit_num]
  261. end if
  262.            mov  edx,sb_base_port
  263.            add  byte[edx],10h
  264.            cmp  byte[edx],80h
  265.            jbe  .sb_try_to_detect_at_specified_port
  266. ;error - no SB card detected
  267. .sb_not_found_err:
  268.            xor  eax, eax
  269.            ret
  270.  
  271. .sb_try_to_detect_at_specified_port:
  272.            call sb_reset
  273.            add  dl,8
  274.            mov  ecx,100
  275. .sb_check_port:
  276.            in   al,dx
  277.            test al,al            ;is DSP port ready to be read?
  278.            jns  .sb_port_not_ready
  279.  
  280.            sub  dl,4
  281.            in   al,dx            ;check for AAh response
  282.            add  dl,4
  283.            cmp  al,0xAA
  284.            jne  .sb_port_not_ready
  285. .sb_card_found:
  286.            and  dl,0xF0
  287.            add  dl,0xC
  288.            sb_out 0xE1           ;get DSP version
  289.            add  dl,2
  290. @@:
  291.            in   al,dx
  292.            test al,al            ;is DSP port ready to be read?
  293.            jns  @b
  294.            sub  dl,4
  295.            in   al,dx            ;get major version
  296.            ror  eax,16
  297.            add  dl,4
  298. @@:
  299.            in   al,dx
  300.            test al,al            ;is DSP port ready to be read?
  301.            jns  @b
  302.            sub  dl,4
  303.            in   al,dx            ;get minor version
  304.            xor  edx,edx
  305.            mov  dl,10
  306.            div  dl
  307.            ror  eax,16
  308.            xor  ah,ah
  309.            mov  [sb_DSP_version_int],eax ;for internal usage
  310. if DEBUG
  311.            add  [sb_DSP_version],eax
  312. end if
  313.            ret
  314.  
  315. .sb_port_not_ready:
  316.            loop .sb_check_port   ;100 retries (~100 microsec.)
  317.            jmp  .sb_detect_next_port
  318. endp
  319. ;-------------------------------------------------------------------------------
  320. if DEBUG
  321. proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
  322.            mov  ebx,eax
  323.            mov  ecx,8
  324.            mov  esi,(number_to_out+1)
  325. .1:
  326.            mov  eax,ebx
  327.            and  eax,0xF
  328.            add  al,'0'
  329.            cmp  al,(10+'0')
  330.            jb   @f
  331.            add  al,('A'-'0'-10)
  332. @@:
  333.            mov  [esi+ecx],al
  334.            shr  ebx,4
  335.            loop .1
  336.            dec  esi
  337.            call SysMsgBoardStr
  338.            ret
  339. endp
  340. end if
  341. ;all initialized data place here
  342. align 4
  343. version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
  344.  
  345. sb_base_port: dd 200h ;don't ask me why - see the code&docs
  346.  
  347. sound_dma     dd sb_dma_num
  348.  
  349. ;note that 4th DMA channel doesn't exist, it is used for cascade
  350. ;plugging the first DMA controler to the second
  351. dma_table     db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
  352.  
  353. my_service    db 'SOUND',0  ;max 16 chars include zero
  354.  
  355. if DEBUG
  356. number_to_out db '0x00000000',13,10,0
  357.  
  358. msgInit       db 'detecting hardware...',13,10,0
  359. msgExit       db 'exiting... May be some problems found?',13,10,0
  360. msgPlay       db 'start play',13,10,0
  361. ;msgStop       db 'stop play',13,10,0
  362. msgCallback   db 'set_callback received from the mixer!',13,10
  363.               db 'callback handler is: ',0
  364. msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
  365.               db 'owner',39,'s handler: ',0
  366. msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
  367.               db ' as hardcoded',13,10,0
  368. msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
  369.               db 'Driver may work unstable',13,10,0
  370. msgSetVol     db 'DEV_SET_MASTERVOL call came',13,10,0
  371. msgGetVol     db 'DEV_GET_MASTERVOL call came',13,10,0
  372. msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
  373. ;-------------------------------------------------------------------------------
  374. msgDSPFound   db 'DSP found at port 2'
  375. label port_second_digit_num dword at $
  376.               db '00h',13,10,'DSP version '
  377. sb_DSP_version: db '0.00 - SB'
  378. sb_DSP_description: db 32,32,32,32,13,10,0
  379. ;-------------------------------------------------------------------------------
  380. end if
  381.  
  382. section '.data' data readable writable align 16
  383. ;all uninitialized data place here
  384.  
  385. ;pTempBuf          rd 1
  386.  
  387. callback           rd 1
  388.  
  389. int_flip_flop      rd 1
  390.  
  391. sb_master_vol      rd 1
  392.  
  393. sb_DSP_version_int rd 1
  394.