Subversion Repositories Kolibri OS

Rev

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
  133.  
  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 bytes
  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. ;       set the rate for playing, enable stereo
  197. ;-------------------------------------------------------------------------------
  198. proc sb_setup
  199.         mov  edx,[sb_base_port]
  200.         add  dl,0xC
  201.         sb_out 40h  ;set time constant, this is for old cards
  202.         sb_out sb_tc
  203.  
  204.         sb_out 41h  ;set sound rate, this can only SB16
  205.         sb_out (sb_out_rate shr 8)    ;first high byte (MSB)
  206.         sb_out (sb_out_rate and 0xff) ;then low byte (LSB)
  207. ;        mov  al,0xE
  208. ;        sub  dl,(0xC-4) ;talk to SB's mixer
  209. ;        out  dx,al      ;select this register of the mixer
  210. ;        mov  ecx,6      ;wait for the chip
  211. ;@@:
  212. ;        in   al,dx
  213. ;        loop @b
  214.  
  215. ;        inc  edx        ;now read the data port
  216. ;        in   al,dx
  217. ;        or   al,22h     ;turn on stereo
  218. ;        mov  ah,al
  219.  
  220. ;        mov  al,0xE
  221. ;        dec  edx        ;talk to SB's mixer
  222. ;        out  dx,al      ;select this register of the mixer
  223.  
  224. ;        mov  ecx,6      ;wait for the chip
  225. ;@@:
  226. ;        in   al,dx
  227. ;        loop @b
  228.  
  229. ;        inc  edx        ;now send data to the data port
  230. ;        mov  al,ah
  231. ;        out  dx,al
  232.  
  233. ;        dec   edx
  234. ;        mov   ecx,35     ;wait for the chip
  235. ;@@:
  236. ;        in   al,dx
  237. ;        loop @b
  238.         ret
  239. endp