Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 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
;-------------------------------------------------------------------------------