Subversion Repositories Kolibri OS

Rev

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