Subversion Repositories Kolibri OS

Rev

Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2465 Serge 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
 
802 serge 8
;--------------------------------
9
;        program dma
10
;--------------------------------
11
sb_set_dma:
2434 Serge 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
802 serge 17
.dma_setup_error:
18
if DEBUG
2434 Serge 19
        mov     esi, msgErrDMAsetup
20
        call    SysMsgBoardStr
802 serge 21
end if
2434 Serge 22
        mov     dword[esp], START.stop
23
        ret
802 serge 24
@@:
25
if use_cli_sti
2434 Serge 26
        cli         ;here to minimize time with disabled ints
802 serge 27
end if
2434 Serge 28
        out     0xA, al;mask required channel
802 serge 29
 
2434 Serge 30
        xor     eax, eax
31
        out     0xC, al;clear byte pointer flip-flop register
802 serge 32
 
2434 Serge 33
        lea     eax, [ebx+0x58];auto-init mode for channel (ebx)
34
        out     0xB, al;DMA channel 0-3 mode register
802 serge 35
 
2434 Serge 36
        movzx   edx, byte[ebx+dma_table];page register
37
        mov     al, DMAPage
38
        out     dx, al
802 serge 39
 
2434 Serge 40
        lea     edx, [ebx*2];DMA channel 0-3 base address
802 serge 41
 
2434 Serge 42
        mov     al, 0;LSB is 0
43
        out     dx, al
802 serge 44
 
45
;        mov al,0   ;MSB is 0 too
2434 Serge 46
        out     dx, al
802 serge 47
 
2434 Serge 48
        inc     edx ;DMA channel 0-3 byte count
802 serge 49
 
2434 Serge 50
        mov     al, ((sb_buffer_size-1) and 0xff)
51
        out     dx, al
802 serge 52
 
2434 Serge 53
        mov     al, ((sb_buffer_size-1) shr 8);it is the same
54
        out     dx, al
802 serge 55
 
2434 Serge 56
        mov     eax, ebx;unmask DMA channel
57
        out     0xA, al
802 serge 58
 
59
if use_cli_sti
2434 Serge 60
        sti
802 serge 61
end if
2434 Serge 62
        ret
802 serge 63
 
64
.use_second_dma_controller:
2434 Serge 65
        cmp     bl, 7
66
        ja      .dma_setup_error
802 serge 67
 
2434 Serge 68
        sub     bl, 4
69
        sub     al, 4
802 serge 70
if use_cli_sti
2434 Serge 71
        cli         ;here to minimize time with disabled ints
802 serge 72
end if
2434 Serge 73
        out     0xD4, al;mask required channel
802 serge 74
 
2434 Serge 75
        xor     eax, eax
76
        out     0xD8, al;clear byte pointer flip-flop register
802 serge 77
 
2434 Serge 78
        lea     eax, [ebx+0x58];auto-init mode for channel (ebx+4)
79
        out     0xD6, al;DMA channel 4-7 mode register
802 serge 80
 
2434 Serge 81
        movzx   edx, byte[ebx+dma_table+4];page register
82
        mov     al, DMAPage
83
        out     dx, al
802 serge 84
 
2434 Serge 85
        lea     edx, [ebx*4+0xC0];DMA channel 4-7 base address
802 serge 86
 
2434 Serge 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
802 serge 89
 
90
;        mov al,0   ;MSB is 0 too ;for 16bit DMA this contains
2434 Serge 91
        out     dx, al;A9-A16 lines of address bus
802 serge 92
 
2434 Serge 93
        inc     edx
94
        inc     edx ;DMA channel 4-7 16bit word count
802 serge 95
 
2434 Serge 96
        mov     al, (((sb_buffer_size/2)-1) and 0xff)
97
        out     dx, al
802 serge 98
 
2434 Serge 99
        mov     al, (((sb_buffer_size/2)-1) shr 8)
100
        out     dx, al
802 serge 101
 
2434 Serge 102
        mov     eax, ebx;unmask DMA channel
103
        out     0xD4, al
802 serge 104
 
105
if use_cli_sti
2434 Serge 106
        sti
802 serge 107
end if
2434 Serge 108
        ret
802 serge 109
;-------------------------------------------------------------------------------
110
;       out byte to SB DSP's write port
111
;-------------------------------------------------------------------------------
2434 Serge 112
macro   sb_out data_to_out {
802 serge 113
@@:
2434 Serge 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
802 serge 119
}
120
;-------------------------------------------------------------------------------
121
;       stop playing
122
;-------------------------------------------------------------------------------
123
proc sb_stop
2434 Serge 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
802 serge 130
endp
131
;-------------------------------------------------------------------------------
132
;       start playing
133
;-------------------------------------------------------------------------------
134
proc sb_play
2434 Serge 135
        and     [int_flip_flop], 0
136
        mov     edx, [sb_base_port]
137
        add     dl, 0xC
138
        sb_out 0xD1 ;turn speaker on
850 serge 139
;        sb_out 0x48 ;set DSP transfer size  ;for older cards, not supported
140
;                                            ;in this version
802 serge 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
;              ||||
2434 Serge 159
        sb_out 10110110b ;bCommand
802 serge 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
;                ||
2434 Serge 168
        sb_out 00110000b ;bMode
802 serge 169
;              ||  ||||
170
;              ---------reserved
171
;wSize is a number of 16bit samples less 1. For auto-init mode each half
850 serge 172
;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples
2434 Serge 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
802 serge 176
endp
177
;-------------------------------------------------------------------------------
178
;       reset DSP
179
;-------------------------------------------------------------------------------
180
proc sb_reset
2434 Serge 181
        and     [int_flip_flop], 0
182
        mov     edx, [sb_base_port]
183
        add     dl, 6
184
        mov     al, 1;start DSP reset
802 serge 185
 
186
if use_cli_sti
2434 Serge 187
        cli         ;here to minimize time with disabled ints
802 serge 188
end if
2434 Serge 189
        out     dx, al
190
        mov     ecx, 40;wait at least 3 microsec.
802 serge 191
@@:
2434 Serge 192
        in      al, dx
193
        loop    @b
802 serge 194
 
2434 Serge 195
        xor     eax, eax;stop DSP reset
802 serge 196
if use_cli_sti
2434 Serge 197
        sti
802 serge 198
end if
2434 Serge 199
        out     dx, al
200
        ret
802 serge 201
endp
850 serge 202
 
802 serge 203
;-------------------------------------------------------------------------------
204
;       set the rate for playing, enable stereo
205
;-------------------------------------------------------------------------------
206
proc sb_setup
2434 Serge 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
802 serge 211
 
2434 Serge 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)
850 serge 215
 
216
;        mov  al,0xE  ;for older cards, not supported in this version
802 serge 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
2434 Serge 247
        ret
850 serge 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
2434 Serge 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
850 serge 303
endp
304
;-------------------------------------------------------------------------------