Subversion Repositories Kolibri OS

Rev

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

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