Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 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
;-------------------------------------------------------------------------------