Subversion Repositories Kolibri OS

Rev

Rev 2288 | 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. ;--------------------------------
  9. ;        program dma
  10. ;--------------------------------
  11. sb_set_dma:
  12.         mov     ebx, [sound_dma]
  13.         lea     eax, [ebx+4];mask required channel
  14.         cmp     bl, 4
  15.         ja      .use_second_dma_controller
  16.         jb      @f
  17. .dma_setup_error:
  18. if DEBUG
  19.         mov     esi, msgErrDMAsetup
  20.         call    SysMsgBoardStr
  21. end if
  22.         mov     dword[esp], START.stop
  23.         ret
  24. @@:
  25. if use_cli_sti
  26.         cli         ;here to minimize time with disabled ints
  27. end if
  28.         out     0xA, al;mask required channel
  29.  
  30.         xor     eax, eax
  31.         out     0xC, al;clear byte pointer flip-flop register
  32.  
  33.         lea     eax, [ebx+0x58];auto-init mode for channel (ebx)
  34.         out     0xB, al;DMA channel 0-3 mode register
  35.  
  36.         movzx   edx, byte[ebx+dma_table];page register
  37.         mov     al, DMAPage
  38.         out     dx, al
  39.  
  40.         lea     edx, [ebx*2];DMA channel 0-3 base address
  41.  
  42.         mov     al, 0;LSB is 0
  43.         out     dx, al
  44.  
  45. ;        mov al,0   ;MSB is 0 too
  46.         out     dx, al
  47.  
  48.         inc     edx ;DMA channel 0-3 byte count
  49.  
  50.         mov     al, ((sb_buffer_size-1) and 0xff)
  51.         out     dx, al
  52.  
  53.         mov     al, ((sb_buffer_size-1) shr 8);it is the same
  54.         out     dx, al
  55.  
  56.         mov     eax, ebx;unmask DMA channel
  57.         out     0xA, al
  58.  
  59. if use_cli_sti
  60.         sti
  61. end if
  62.         ret
  63.  
  64. .use_second_dma_controller:
  65.         cmp     bl, 7
  66.         ja      .dma_setup_error
  67.  
  68.         sub     bl, 4
  69.         sub     al, 4
  70. if use_cli_sti
  71.         cli         ;here to minimize time with disabled ints
  72. end if
  73.         out     0xD4, al;mask required channel
  74.  
  75.         xor     eax, eax
  76.         out     0xD8, al;clear byte pointer flip-flop register
  77.  
  78.         lea     eax, [ebx+0x58];auto-init mode for channel (ebx+4)
  79.         out     0xD6, al;DMA channel 4-7 mode register
  80.  
  81.         movzx   edx, byte[ebx+dma_table+4];page register
  82.         mov     al, DMAPage
  83.         out     dx, al
  84.  
  85.         lea     edx, [ebx*4+0xC0];DMA channel 4-7 base address
  86.  
  87.         mov     al, 0;LSB is 0 ;for 16bit DMA this contains
  88.         out     dx, al;A1-A8 lines of address bus, A0 is zero
  89.  
  90. ;        mov al,0   ;MSB is 0 too ;for 16bit DMA this contains
  91.         out     dx, al;A9-A16 lines of address bus
  92.  
  93.         inc     edx
  94.         inc     edx ;DMA channel 4-7 16bit word count
  95.  
  96.         mov     al, (((sb_buffer_size/2)-1) and 0xff)
  97.         out     dx, al
  98.  
  99.         mov     al, (((sb_buffer_size/2)-1) shr 8)
  100.         out     dx, al
  101.  
  102.         mov     eax, ebx;unmask DMA channel
  103.         out     0xD4, al
  104.  
  105. if use_cli_sti
  106.         sti
  107. end if
  108.         ret
  109. ;-------------------------------------------------------------------------------
  110. ;       out byte to SB DSP's write port
  111. ;-------------------------------------------------------------------------------
  112. macro   sb_out data_to_out {
  113. @@:
  114.         in      al, dx
  115.         test    al, al;is DSP busy?
  116.         js      @b  ;it's busy
  117.         mov     al, data_to_out;it's free
  118.         out     dx, al
  119. }
  120. ;-------------------------------------------------------------------------------
  121. ;       stop playing
  122. ;-------------------------------------------------------------------------------
  123. proc sb_stop
  124.         mov     edx, [sb_base_port]
  125.         add     dl, 0xC
  126.         sb_out 0xD3 ;turn the speaker off
  127.         sb_out 0xDA ;exit 8bit DMA
  128.         sb_out 0xD9 ;exit 16bit DMA
  129.         ret
  130. endp
  131. ;-------------------------------------------------------------------------------
  132. ;       start playing
  133. ;-------------------------------------------------------------------------------
  134. proc sb_play
  135.         and     [int_flip_flop], 0
  136.         mov     edx, [sb_base_port]
  137.         add     dl, 0xC
  138.         sb_out 0xD1 ;turn speaker on
  139. ;        sb_out 0x48 ;set DSP transfer size  ;for older cards, not supported
  140. ;                                            ;in this version
  141. ;        mov  ax,32767 ;(64k)/2-1
  142. ;@@:                 ;out the low byte...
  143. ;        in   al,dx
  144. ;        test al,al  ;is DSP busy?
  145. ;        js   @b     ;it's busy
  146. ;        out  dx,al
  147.  
  148. ;        mov  al,ah  ;...then the high byte
  149. ;@@:
  150. ;        in   al,dx
  151. ;        test al,al  ;is DSP busy?
  152. ;        js   @b     ;it's busy
  153. ;        out  dx,al
  154.  
  155. ;        sb_out 0x1C ;auto-init 8bit playback
  156.  
  157. ;              0xBXh - 16 bit DMA mode
  158. ;              ||||
  159.         sb_out 10110110b ;bCommand
  160. ;                  ||||
  161. ;                  |||+-reserved
  162. ;                  ||+--turn FIFO on (0 for off)
  163. ;                  |+---auto-init mode on (0 for off)
  164. ;                  +----A/D: 0-output, 1-input
  165. ;                +------stereo on
  166. ;                |+-----unsigned (1 for signed)
  167. ;                ||
  168.         sb_out 00110000b ;bMode
  169. ;              ||  ||||
  170. ;              ---------reserved
  171. ;wSize is a number of 16bit samples less 1. For auto-init mode each half
  172. ;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples
  173.         sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte
  174.         sb_out (((sb_buffer_size/2/2)-1) shr 8)    ;wSize.HighByte
  175.         ret
  176. endp
  177. ;-------------------------------------------------------------------------------
  178. ;       reset DSP
  179. ;-------------------------------------------------------------------------------
  180. proc sb_reset
  181.         and     [int_flip_flop], 0
  182.         mov     edx, [sb_base_port]
  183.         add     dl, 6
  184.         mov     al, 1;start DSP reset
  185.  
  186. if use_cli_sti
  187.         cli         ;here to minimize time with disabled ints
  188. end if
  189.         out     dx, al
  190.         mov     ecx, 40;wait at least 3 microsec.
  191. @@:
  192.         in      al, dx
  193.         loop    @b
  194.  
  195.         xor     eax, eax;stop DSP reset
  196. if use_cli_sti
  197.         sti
  198. end if
  199.         out     dx, al
  200.         ret
  201. endp
  202.  
  203. ;-------------------------------------------------------------------------------
  204. ;       set the rate for playing, enable stereo
  205. ;-------------------------------------------------------------------------------
  206. proc sb_setup
  207.         mov     edx, [sb_base_port]
  208.         add     dl, 0xC
  209.         sb_out 40h  ;set time constant, this is for old cards
  210.         sb_out sb_tc
  211.  
  212.         sb_out 41h  ;set sound rate, this can only SB16
  213.         sb_out (sb_out_rate shr 8)    ;first high byte (MSB)
  214.         sb_out (sb_out_rate and 0xff) ;then low byte (LSB)
  215.  
  216. ;        mov  al,0xE  ;for older cards, not supported in this version
  217. ;        sub  dl,(0xC-4) ;talk to SB's mixer
  218. ;        out  dx,al      ;select this register of the mixer
  219. ;        mov  ecx,6      ;wait for the chip
  220. ;@@:
  221. ;        in   al,dx
  222. ;        loop @b
  223.  
  224. ;        inc  edx        ;now read the data port
  225. ;        in   al,dx
  226. ;        or   al,22h     ;turn on stereo
  227. ;        mov  ah,al
  228.  
  229. ;        mov  al,0xE
  230. ;        dec  edx        ;talk to SB's mixer
  231. ;        out  dx,al      ;select this register of the mixer
  232.  
  233. ;        mov  ecx,6      ;wait for the chip
  234. ;@@:
  235. ;        in   al,dx
  236. ;        loop @b
  237.  
  238. ;        inc  edx        ;now send data to the data port
  239. ;        mov  al,ah
  240. ;        out  dx,al
  241.  
  242. ;        dec   edx
  243. ;        mov   ecx,35     ;wait for the chip
  244. ;@@:
  245. ;        in   al,dx
  246. ;        loop @b
  247.         ret
  248. endp
  249.  
  250. ;-------------------------------------------------------------------------------
  251. ;       set master volume of SB mixer, note, not only SB16 but SBPro and older
  252. ;       this is the first step to more full support for hardware
  253. ;-------------------------------------------------------------------------------
  254. ;in: eax in range [-10000;0] - master volume for _both_ channels
  255. ;note that x*3*17/2000 and x*3/2000*17 are not the same numbers,
  256. ;because we count in integers
  257. proc sb_set_master_vol
  258.         mov     [sb_master_vol], eax
  259.         add     eax, 10000;SB sound level rise from 0 to MAX_LEVEL
  260.         lea     eax, [eax+eax*2];*3
  261.         mov     ebx, 2000;divisor
  262.         xor     edx, edx
  263.         cmp     byte[sb_DSP_version_int], 4
  264.         jae     @f    ;SBPro's MAX_LEVEL is 15, but we *11 because
  265.                       ;volume byte looks like that: 0xLR, where L - left
  266.                       ;channel volume, R - right, 0<=R,L<=15
  267.         div     ebx
  268.         imul    eax, 17
  269.         mov     edx, [sb_base_port]
  270.         push    eax   ;here for optimisation
  271.         add     dl, 4
  272.         mov     al, 0x22;write mixer register 0x22
  273.         out     dx, al
  274.         in      al, dx;wait for the chip ;6
  275.         in      al, dx;wait for the chip ;5
  276.         in      al, dx;wait for the chip ;4
  277.         in      al, dx;wait for the chip ;3
  278.         in      al, dx;wait for the chip ;2
  279.         in      al, dx;wait for the chip ;1
  280.         pop     eax                      ;go!
  281.         inc     edx
  282.         out     dx, al
  283.         ret
  284. @@:                   ;SB16's MAX_LEVEL is 255
  285.         imul    eax, 17
  286.         div     ebx
  287.         mov     edx, [sb_base_port]
  288.         push    eax   ;here for optimisation
  289.         add     dl, 4
  290.         mov     al, 0x30;left speaker
  291.         out     dx, al
  292.         pop     eax   ;<--+
  293.         inc     edx   ;   \/
  294.         push    eax   ;here for optimisation
  295.         out     dx, al;write
  296.         dec     edx
  297.         mov     al, 0x31;right speaker
  298.         out     dx, al
  299.         pop     eax
  300.         inc     edx
  301.         out     dx, al;write
  302.         ret
  303. endp
  304. ;-------------------------------------------------------------------------------
  305.