Rev 837 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
802 | serge | 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 |
||
133 | |||
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 bytes |
||
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 | ; set the rate for playing, enable stereo |
||
197 | ;------------------------------------------------------------------------------- |
||
198 | proc sb_setup |
||
199 | mov edx,[sb_base_port] |
||
200 | add dl,0xC |
||
201 | sb_out 40h ;set time constant, this is for old cards |
||
202 | sb_out sb_tc |
||
203 | |||
204 | sb_out 41h ;set sound rate, this can only SB16 |
||
205 | sb_out (sb_out_rate shr 8) ;first high byte (MSB) |
||
206 | sb_out (sb_out_rate and 0xff) ;then low byte (LSB) |
||
207 | ; mov al,0xE |
||
208 | ; sub dl,(0xC-4) ;talk to SB's mixer |
||
209 | ; out dx,al ;select this register of the mixer |
||
210 | ; mov ecx,6 ;wait for the chip |
||
211 | ;@@: |
||
212 | ; in al,dx |
||
213 | ; loop @b |
||
214 | |||
215 | ; inc edx ;now read the data port |
||
216 | ; in al,dx |
||
217 | ; or al,22h ;turn on stereo |
||
218 | ; mov ah,al |
||
219 | |||
220 | ; mov al,0xE |
||
221 | ; dec edx ;talk to SB's mixer |
||
222 | ; out dx,al ;select this register of the mixer |
||
223 | |||
224 | ; mov ecx,6 ;wait for the chip |
||
225 | ;@@: |
||
226 | ; in al,dx |
||
227 | ; loop @b |
||
228 | |||
229 | ; inc edx ;now send data to the data port |
||
230 | ; mov al,ah |
||
231 | ; out dx,al |
||
232 | |||
233 | ; dec edx |
||
234 | ; mov ecx,35 ;wait for the chip |
||
235 | ;@@: |
||
236 | ; in al,dx |
||
237 | ; loop @b |
||
238 | ret |
||
239 | endp |