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