Rev 5057 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5057 | Rev 5363 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | ;-------------------------------- |
8 | ;-------------------------------- |
9 | ; program dma |
9 | ; program dma |
10 | ;-------------------------------- |
10 | ;-------------------------------- |
11 | sb_set_dma: |
11 | sb_set_dma: |
12 | mov ebx, [sound_dma] |
12 | mov ebx, [sound_dma] |
13 | lea eax, [ebx+4];mask required channel |
13 | lea eax, [ebx+4];mask required channel |
14 | cmp bl, 4 |
14 | cmp bl, 4 |
15 | ja .use_second_dma_controller |
15 | ja .use_second_dma_controller |
16 | jb @f |
16 | jb @f |
17 | .dma_setup_error: |
17 | .dma_setup_error: |
18 | if DEBUG |
18 | if DEBUG |
19 | mov esi, msgErrDMAsetup |
19 | mov esi, msgErrDMAsetup |
20 | invoke SysMsgBoardStr |
20 | invoke SysMsgBoardStr |
21 | end if |
21 | end if |
22 | mov dword[esp], START.stop |
22 | mov dword[esp], START.stop |
23 | ret |
23 | ret |
24 | @@: |
24 | @@: |
25 | if use_cli_sti |
25 | if use_cli_sti |
26 | cli ;here to minimize time with disabled ints |
26 | cli ;here to minimize time with disabled ints |
27 | end if |
27 | end if |
28 | out 0xA, al;mask required channel |
28 | out 0xA, al;mask required channel |
29 | 29 | ||
30 | xor eax, eax |
30 | xor eax, eax |
31 | out 0xC, al;clear byte pointer flip-flop register |
31 | out 0xC, al;clear byte pointer flip-flop register |
32 | 32 | ||
33 | lea eax, [ebx+0x58];auto-init mode for channel (ebx) |
33 | lea eax, [ebx+0x58];auto-init mode for channel (ebx) |
34 | out 0xB, al;DMA channel 0-3 mode register |
34 | out 0xB, al;DMA channel 0-3 mode register |
35 | 35 | ||
36 | mov eax, [SB16Buffer] |
36 | mov eax, [SB16Buffer] |
37 | invoke GetPhysAddr |
37 | invoke GetPhysAddr |
38 | mov ecx, eax |
38 | mov ecx, eax |
39 | shr eax, 16 |
39 | shr eax, 16 |
40 | 40 | ||
41 | movzx edx, byte[ebx+dma_table];page register |
41 | movzx edx, byte[ebx+dma_table];page register |
42 | out dx, al |
42 | out dx, al |
43 | 43 | ||
44 | lea edx, [ebx*2];DMA channel 0-3 base address |
44 | lea edx, [ebx*2];DMA channel 0-3 base address |
45 | 45 | ||
46 | mov al, cl;LSB |
46 | mov al, cl;LSB |
47 | out dx, al |
47 | out dx, al |
48 | 48 | ||
49 | mov al, ch;MSB |
49 | mov al, ch;MSB |
50 | out dx, al |
50 | out dx, al |
51 | 51 | ||
52 | inc edx ;DMA channel 0-3 byte count |
52 | inc edx ;DMA channel 0-3 byte count |
53 | 53 | ||
54 | mov al, ((sb_buffer_size-1) and 0xff) |
54 | mov al, ((sb_buffer_size-1) and 0xff) |
55 | out dx, al |
55 | out dx, al |
56 | 56 | ||
57 | mov al, ((sb_buffer_size-1) shr 8);it is the same |
57 | mov al, ((sb_buffer_size-1) shr 8);it is the same |
58 | out dx, al |
58 | out dx, al |
59 | 59 | ||
60 | mov eax, ebx;unmask DMA channel |
60 | mov eax, ebx;unmask DMA channel |
61 | out 0xA, al |
61 | out 0xA, al |
62 | 62 | ||
63 | if use_cli_sti |
63 | if use_cli_sti |
64 | sti |
64 | sti |
65 | end if |
65 | end if |
66 | ret |
66 | ret |
67 | 67 | ||
68 | .use_second_dma_controller: |
68 | .use_second_dma_controller: |
69 | cmp bl, 7 |
69 | cmp bl, 7 |
70 | ja .dma_setup_error |
70 | ja .dma_setup_error |
71 | 71 | ||
72 | sub bl, 4 |
72 | sub bl, 4 |
73 | sub al, 4 |
73 | sub al, 4 |
74 | if use_cli_sti |
74 | if use_cli_sti |
75 | cli ;here to minimize time with disabled ints |
75 | cli ;here to minimize time with disabled ints |
76 | end if |
76 | end if |
77 | out 0xD4, al;mask required channel |
77 | out 0xD4, al;mask required channel |
78 | 78 | ||
79 | xor eax, eax |
79 | xor eax, eax |
80 | out 0xD8, al;clear byte pointer flip-flop register |
80 | out 0xD8, al;clear byte pointer flip-flop register |
81 | 81 | ||
82 | lea eax, [ebx+0x58];auto-init mode for channel (ebx+4) |
82 | lea eax, [ebx+0x58];auto-init mode for channel (ebx+4) |
83 | out 0xD6, al;DMA channel 4-7 mode register |
83 | out 0xD6, al;DMA channel 4-7 mode register |
84 | 84 | ||
85 | mov eax, [SB16Buffer] |
85 | mov eax, [SB16Buffer] |
86 | invoke GetPhysAddr |
86 | invoke GetPhysAddr |
87 | mov ecx, eax |
87 | mov ecx, eax |
88 | shr eax, 16 |
88 | shr eax, 16 |
89 | shr ecx, 1 ; 16-bit DMA takes offset in words |
89 | shr ecx, 1 ; 16-bit DMA takes offset in words |
90 | 90 | ||
91 | movzx edx, byte[ebx+dma_table+4];page register |
91 | movzx edx, byte[ebx+dma_table+4];page register |
92 | out dx, al |
92 | out dx, al |
93 | 93 | ||
94 | lea edx, [ebx*4+0xC0];DMA channel 4-7 base address |
94 | lea edx, [ebx*4+0xC0];DMA channel 4-7 base address |
95 | 95 | ||
96 | mov al, cl;LSB;for 16bit DMA this contains |
96 | mov al, cl;LSB;for 16bit DMA this contains |
97 | out dx, al;A1-A8 lines of address bus, A0 is zero |
97 | out dx, al;A1-A8 lines of address bus, A0 is zero |
98 | 98 | ||
99 | mov al, ch;MSB;for 16bit DMA this contains |
99 | mov al, ch;MSB;for 16bit DMA this contains |
100 | out dx, al;A9-A16 lines of address bus |
100 | out dx, al;A9-A16 lines of address bus |
101 | 101 | ||
102 | inc edx |
102 | inc edx |
103 | inc edx ;DMA channel 4-7 16bit word count |
103 | inc edx ;DMA channel 4-7 16bit word count |
104 | 104 | ||
105 | mov al, (((sb_buffer_size/2)-1) and 0xff) |
105 | mov al, (((sb_buffer_size/2)-1) and 0xff) |
106 | out dx, al |
106 | out dx, al |
107 | 107 | ||
108 | mov al, (((sb_buffer_size/2)-1) shr 8) |
108 | mov al, (((sb_buffer_size/2)-1) shr 8) |
109 | out dx, al |
109 | out dx, al |
110 | 110 | ||
111 | mov eax, ebx;unmask DMA channel |
111 | mov eax, ebx;unmask DMA channel |
112 | out 0xD4, al |
112 | out 0xD4, al |
113 | 113 | ||
114 | if use_cli_sti |
114 | if use_cli_sti |
115 | sti |
115 | sti |
116 | end if |
116 | end if |
117 | ret |
117 | ret |
118 | ;------------------------------------------------------------------------------- |
118 | ;------------------------------------------------------------------------------- |
119 | ; out byte to SB DSP's write port |
119 | ; out byte to SB DSP's write port |
120 | ;------------------------------------------------------------------------------- |
120 | ;------------------------------------------------------------------------------- |
121 | macro sb_out data_to_out { |
121 | macro sb_out data_to_out { |
122 | @@: |
122 | @@: |
123 | in al, dx |
123 | in al, dx |
124 | test al, al;is DSP busy? |
124 | test al, al;is DSP busy? |
125 | js @b ;it's busy |
125 | js @b ;it's busy |
126 | mov al, data_to_out;it's free |
126 | mov al, data_to_out;it's free |
127 | out dx, al |
127 | out dx, al |
128 | } |
128 | } |
129 | ;------------------------------------------------------------------------------- |
129 | ;------------------------------------------------------------------------------- |
130 | ; stop playing |
130 | ; stop playing |
131 | ;------------------------------------------------------------------------------- |
131 | ;------------------------------------------------------------------------------- |
132 | proc sb_stop |
132 | proc sb_stop |
133 | mov edx, [sb_base_port] |
133 | mov edx, [sb_base_port] |
134 | add dl, 0xC |
134 | add dl, 0xC |
135 | sb_out 0xD3 ;turn the speaker off |
135 | sb_out 0xD3 ;turn the speaker off |
136 | sb_out 0xDA ;exit 8bit DMA |
136 | sb_out 0xDA ;exit 8bit DMA |
137 | sb_out 0xD9 ;exit 16bit DMA |
137 | sb_out 0xD9 ;exit 16bit DMA |
138 | ret |
138 | ret |
139 | endp |
139 | endp |
140 | ;------------------------------------------------------------------------------- |
140 | ;------------------------------------------------------------------------------- |
141 | ; start playing |
141 | ; start playing |
142 | ;------------------------------------------------------------------------------- |
142 | ;------------------------------------------------------------------------------- |
143 | proc sb_play |
143 | proc sb_play |
144 | and [int_flip_flop], 0 |
144 | and [int_flip_flop], 0 |
145 | mov edx, [sb_base_port] |
145 | mov edx, [sb_base_port] |
146 | add dl, 0xC |
146 | add dl, 0xC |
147 | sb_out 0xD1 ;turn speaker on |
147 | sb_out 0xD1 ;turn speaker on |
148 | ; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported |
148 | ; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported |
149 | ; ;in this version |
149 | ; ;in this version |
150 | ; mov ax,32767 ;(64k)/2-1 |
150 | ; mov ax,32767 ;(64k)/2-1 |
151 | ;@@: ;out the low byte... |
151 | ;@@: ;out the low byte... |
152 | ; in al,dx |
152 | ; in al,dx |
153 | ; test al,al ;is DSP busy? |
153 | ; test al,al ;is DSP busy? |
154 | ; js @b ;it's busy |
154 | ; js @b ;it's busy |
155 | ; out dx,al |
155 | ; out dx,al |
156 | 156 | ||
157 | ; mov al,ah ;...then the high byte |
157 | ; mov al,ah ;...then the high byte |
158 | ;@@: |
158 | ;@@: |
159 | ; in al,dx |
159 | ; in al,dx |
160 | ; test al,al ;is DSP busy? |
160 | ; test al,al ;is DSP busy? |
161 | ; js @b ;it's busy |
161 | ; js @b ;it's busy |
162 | ; out dx,al |
162 | ; out dx,al |
163 | 163 | ||
164 | ; sb_out 0x1C ;auto-init 8bit playback |
164 | ; sb_out 0x1C ;auto-init 8bit playback |
165 | 165 | ||
166 | ; 0xBXh - 16 bit DMA mode |
166 | ; 0xBXh - 16 bit DMA mode |
167 | ; |||| |
167 | ; |||| |
168 | sb_out 10110110b ;bCommand |
168 | sb_out 10110110b ;bCommand |
169 | ; |||| |
169 | ; |||| |
170 | ; |||+-reserved |
170 | ; |||+-reserved |
171 | ; ||+--turn FIFO on (0 for off) |
171 | ; ||+--turn FIFO on (0 for off) |
172 | ; |+---auto-init mode on (0 for off) |
172 | ; |+---auto-init mode on (0 for off) |
173 | ; +----A/D: 0-output, 1-input |
173 | ; +----A/D: 0-output, 1-input |
174 | ; +------stereo on |
174 | ; +------stereo on |
175 | ; |+-----unsigned (1 for signed) |
175 | ; |+-----unsigned (1 for signed) |
176 | ; || |
176 | ; || |
177 | sb_out 00110000b ;bMode |
177 | sb_out 00110000b ;bMode |
178 | ; || |||| |
178 | ; || |||| |
179 | ; ---------reserved |
179 | ; ---------reserved |
180 | ;wSize is a number of 16bit samples less 1. For auto-init mode each half |
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 |
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 |
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 |
183 | sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte |
184 | ret |
184 | ret |
185 | endp |
185 | endp |
186 | ;------------------------------------------------------------------------------- |
186 | ;------------------------------------------------------------------------------- |
187 | ; reset DSP |
187 | ; reset DSP |
188 | ;------------------------------------------------------------------------------- |
188 | ;------------------------------------------------------------------------------- |
189 | proc sb_reset |
189 | proc sb_reset |
190 | and [int_flip_flop], 0 |
190 | and [int_flip_flop], 0 |
191 | mov edx, [sb_base_port] |
191 | mov edx, [sb_base_port] |
192 | add dl, 6 |
192 | add dl, 6 |
193 | mov al, 1;start DSP reset |
193 | mov al, 1;start DSP reset |
194 | 194 | ||
195 | if use_cli_sti |
195 | if use_cli_sti |
196 | cli ;here to minimize time with disabled ints |
196 | cli ;here to minimize time with disabled ints |
197 | end if |
197 | end if |
198 | out dx, al |
198 | out dx, al |
199 | mov ecx, 40;wait at least 3 microsec. |
199 | mov ecx, 40;wait at least 3 microsec. |
200 | @@: |
200 | @@: |
201 | in al, dx |
201 | in al, dx |
202 | loop @b |
202 | loop @b |
203 | 203 | ||
204 | xor eax, eax;stop DSP reset |
204 | xor eax, eax;stop DSP reset |
205 | if use_cli_sti |
205 | if use_cli_sti |
206 | sti |
206 | sti |
207 | end if |
207 | end if |
208 | out dx, al |
208 | out dx, al |
209 | ret |
209 | ret |
210 | endp |
210 | endp |
211 | 211 | ||
212 | ;------------------------------------------------------------------------------- |
212 | ;------------------------------------------------------------------------------- |
213 | ; set the rate for playing, enable stereo |
213 | ; set the rate for playing, enable stereo |
214 | ;------------------------------------------------------------------------------- |
214 | ;------------------------------------------------------------------------------- |
215 | proc sb_setup |
215 | proc sb_setup |
216 | mov edx, [sb_base_port] |
216 | mov edx, [sb_base_port] |
217 | add dl, 0xC |
217 | add dl, 0xC |
218 | sb_out 40h ;set time constant, this is for old cards |
218 | sb_out 40h ;set time constant, this is for old cards |
219 | sb_out sb_tc |
219 | sb_out sb_tc |
220 | 220 | ||
221 | sb_out 41h ;set sound rate, this can only SB16 |
221 | sb_out 41h ;set sound rate, this can only SB16 |
222 | sb_out (sb_out_rate shr 8) ;first high byte (MSB) |
222 | sb_out (sb_out_rate shr 8) ;first high byte (MSB) |
223 | sb_out (sb_out_rate and 0xff) ;then low byte (LSB) |
223 | sb_out (sb_out_rate and 0xff) ;then low byte (LSB) |
224 | 224 | ||
225 | ; mov al,0xE ;for older cards, not supported in this version |
225 | ; mov al,0xE ;for older cards, not supported in this version |
226 | ; sub dl,(0xC-4) ;talk to SB's mixer |
226 | ; sub dl,(0xC-4) ;talk to SB's mixer |
227 | ; out dx,al ;select this register of the mixer |
227 | ; out dx,al ;select this register of the mixer |
228 | ; mov ecx,6 ;wait for the chip |
228 | ; mov ecx,6 ;wait for the chip |
229 | ;@@: |
229 | ;@@: |
230 | ; in al,dx |
230 | ; in al,dx |
231 | ; loop @b |
231 | ; loop @b |
232 | 232 | ||
233 | ; inc edx ;now read the data port |
233 | ; inc edx ;now read the data port |
234 | ; in al,dx |
234 | ; in al,dx |
235 | ; or al,22h ;turn on stereo |
235 | ; or al,22h ;turn on stereo |
236 | ; mov ah,al |
236 | ; mov ah,al |
237 | 237 | ||
238 | ; mov al,0xE |
238 | ; mov al,0xE |
239 | ; dec edx ;talk to SB's mixer |
239 | ; dec edx ;talk to SB's mixer |
240 | ; out dx,al ;select this register of the mixer |
240 | ; out dx,al ;select this register of the mixer |
241 | 241 | ||
242 | ; mov ecx,6 ;wait for the chip |
242 | ; mov ecx,6 ;wait for the chip |
243 | ;@@: |
243 | ;@@: |
244 | ; in al,dx |
244 | ; in al,dx |
245 | ; loop @b |
245 | ; loop @b |
246 | 246 | ||
247 | ; inc edx ;now send data to the data port |
247 | ; inc edx ;now send data to the data port |
248 | ; mov al,ah |
248 | ; mov al,ah |
249 | ; out dx,al |
249 | ; out dx,al |
250 | 250 | ||
251 | ; dec edx |
251 | ; dec edx |
252 | ; mov ecx,35 ;wait for the chip |
252 | ; mov ecx,35 ;wait for the chip |
253 | ;@@: |
253 | ;@@: |
254 | ; in al,dx |
254 | ; in al,dx |
255 | ; loop @b |
255 | ; loop @b |
256 | ret |
256 | ret |
257 | endp |
257 | endp |
258 | 258 | ||
259 | ;------------------------------------------------------------------------------- |
259 | ;------------------------------------------------------------------------------- |
260 | ; set master volume of SB mixer, note, not only SB16 but SBPro and older |
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 |
261 | ; this is the first step to more full support for hardware |
262 | ;------------------------------------------------------------------------------- |
262 | ;------------------------------------------------------------------------------- |
263 | ;in: eax in range [-10000;0] - master volume for _both_ channels |
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, |
264 | ;note that x*3*17/2000 and x*3/2000*17 are not the same numbers, |
265 | ;because we count in integers |
265 | ;because we count in integers |
266 | proc sb_set_master_vol |
266 | proc sb_set_master_vol |
267 | mov [sb_master_vol], eax |
267 | mov [sb_master_vol], eax |
268 | add eax, 10000;SB sound level rise from 0 to MAX_LEVEL |
268 | add eax, 10000;SB sound level rise from 0 to MAX_LEVEL |
269 | lea eax, [eax+eax*2];*3 |
269 | lea eax, [eax+eax*2];*3 |
270 | mov ebx, 2000;divisor |
270 | mov ebx, 2000;divisor |
271 | xor edx, edx |
271 | xor edx, edx |
272 | cmp byte[sb_DSP_version_int], 4 |
272 | cmp byte[sb_DSP_version_int], 4 |
273 | jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because |
273 | jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because |
274 | ;volume byte looks like that: 0xLR, where L - left |
274 | ;volume byte looks like that: 0xLR, where L - left |
275 | ;channel volume, R - right, 0<=R,L<=15 |
275 | ;channel volume, R - right, 0<=R,L<=15 |
276 | div ebx |
276 | div ebx |
277 | imul eax, 17 |
277 | imul eax, 17 |
278 | mov edx, [sb_base_port] |
278 | mov edx, [sb_base_port] |
279 | push eax ;here for optimisation |
279 | push eax ;here for optimisation |
280 | add dl, 4 |
280 | add dl, 4 |
281 | mov al, 0x22;write mixer register 0x22 |
281 | mov al, 0x22;write mixer register 0x22 |
282 | out dx, al |
282 | out dx, al |
283 | in al, dx;wait for the chip ;6 |
283 | in al, dx;wait for the chip ;6 |
284 | in al, dx;wait for the chip ;5 |
284 | in al, dx;wait for the chip ;5 |
285 | in al, dx;wait for the chip ;4 |
285 | in al, dx;wait for the chip ;4 |
286 | in al, dx;wait for the chip ;3 |
286 | in al, dx;wait for the chip ;3 |
287 | in al, dx;wait for the chip ;2 |
287 | in al, dx;wait for the chip ;2 |
288 | in al, dx;wait for the chip ;1 |
288 | in al, dx;wait for the chip ;1 |
289 | pop eax ;go! |
289 | pop eax ;go! |
290 | inc edx |
290 | inc edx |
291 | out dx, al |
291 | out dx, al |
292 | ret |
292 | ret |
293 | @@: ;SB16's MAX_LEVEL is 255 |
293 | @@: ;SB16's MAX_LEVEL is 255 |
294 | imul eax, 17 |
294 | imul eax, 17 |
295 | div ebx |
295 | div ebx |
296 | mov edx, [sb_base_port] |
296 | mov edx, [sb_base_port] |
297 | push eax ;here for optimisation |
297 | push eax ;here for optimisation |
298 | add dl, 4 |
298 | add dl, 4 |
299 | mov al, 0x30;left speaker |
299 | mov al, 0x30;left speaker |
300 | out dx, al |
300 | out dx, al |
301 | pop eax ;<--+ |
301 | pop eax ;<--+ |
302 | inc edx ; \/ |
302 | inc edx ; \/ |
303 | push eax ;here for optimisation |
303 | push eax ;here for optimisation |
304 | out dx, al;write |
304 | out dx, al;write |
305 | dec edx |
305 | dec edx |
306 | mov al, 0x31;right speaker |
306 | mov al, 0x31;right speaker |
307 | out dx, al |
307 | out dx, al |
308 | pop eax |
308 | pop eax |
309 | inc edx |
309 | inc edx |
310 | out dx, al;write |
310 | out dx, al;write |
311 | ret |
311 | ret |
312 | endp |
312 | endp |
313 | ;---------------------------------------------------------------------------------+ |
313 | ;---------------------------------------------------------------------------------+ |
314 | >=15 |
314 | >=15 |
315 | >=R,L<=15 |
315 | >=R,L<=15 |
316 | > |
316 | > |