Subversion Repositories Kolibri OS

Rev

Rev 2455 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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