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