Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2455 mario79 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
 
2288 clevermous 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
5057 clevermous 20
        invoke  SysMsgBoardStr
2288 clevermous 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
 
5057 clevermous 36
        mov     eax, [SB16Buffer]
37
        invoke  GetPhysAddr
38
        mov     ecx, eax
39
        shr     eax, 16
40
 
2288 clevermous 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
 
5057 clevermous 46
        mov     al, cl;LSB
2288 clevermous 47
        out     dx, al
48
 
5057 clevermous 49
        mov     al, ch;MSB
2288 clevermous 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
 
5057 clevermous 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
 
2288 clevermous 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
 
5057 clevermous 96
        mov     al, cl;LSB;for 16bit DMA this contains
2288 clevermous 97
        out     dx, al;A1-A8 lines of address bus, A0 is zero
98
 
5057 clevermous 99
        mov     al, ch;MSB;for 16bit DMA this contains
2288 clevermous 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
;-------------------------------------------------------------------------------