Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
802 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
format MS COFF
9
 
2010 serge 10
include 'CONFIG.INC'
802 serge 11
 
12
;structs----------------------------------------------------------
13
struc IOCTL
2434 Serge 14
{  .handle      dd ?
15
   .io_code     dd ?
16
   .input       dd ?
17
   .inp_size    dd ?
18
   .output      dd ?
19
   .out_size    dd ?
802 serge 20
}
21
 
22
virtual at 0
23
  IOCTL IOCTL
24
end virtual
25
 
26
;something--------------------------------------------------------
27
public START
28
public service_proc
29
public version
30
 
31
include '..\proc32.inc'
32
include '..\imports.inc'
33
 
34
section '.flat' code readable align 16
35
 
2010 serge 36
include 'SB16.INC'
802 serge 37
 
38
;-------------------------------------------------------------------------------
39
proc START stdcall, state:dword
2434 Serge 40
        cmp     [state], 1
41
        jne     .stop
802 serge 42
.entry:
43
 
44
if DEBUG
2434 Serge 45
        mov     esi, msgInit
46
        call    SysMsgBoardStr
802 serge 47
end if
48
 
2434 Serge 49
        call    detect           ;returns DSP version or zero if
50
        test    eax, eax         ;SB card not found
51
        jz      .exit
802 serge 52
 
53
if DEBUG
2434 Serge 54
        movzx   eax, al          ;major version
55
        mov     esi, sb_DSP_description
56
        dec     eax
57
        jz      .sb_say_about_found_dsp
58
        mov     dword[esi], '2.x '
59
        dec     eax
60
        jz      .sb_say_about_found_dsp
61
        mov     dword[esi], 'Pro '
62
        dec     eax
63
        jz      .sb_say_about_found_dsp
64
        mov     dword[esi], '16  '
802 serge 65
.sb_say_about_found_dsp:
2434 Serge 66
        mov     esi, msgDSPFound
67
        call    SysMsgBoardStr
802 serge 68
end if
2434 Serge 69
;          xor  eax,eax
70
;          mov  ebx,[sb_base_port]
71
;          lea  ecx,[ebx+0xF]
72
        xor     ebx, ebx
73
        mov     ecx, [sb_base_port]
74
        lea     edx, [ebx+0xF]
1306 Lrz 75
 
2434 Serge 76
        call    ReservePortArea  ;these ports must be my!
802 serge 77
if DEBUG
2434 Serge 78
        dec     eax
79
        jnz     @f
80
        mov     esi, msgErrRsrvPorts
81
        call    SysMsgBoardStr
802 serge 82
@@:
83
end if
84
 
2434 Serge 85
        call    sb_setup         ;clock it, etc
802 serge 86
 
2434 Serge 87
        stdcall AttachIntHandler, sb_irq_num, sb_irq, 0
802 serge 88
 
89
if DEBUG
2434 Serge 90
        test    eax, eax
91
        jnz     @f
802 serge 92
 
2434 Serge 93
        mov     esi, msgErrAtchIRQ
94
        call    SysMsgBoardStr
802 serge 95
 
2434 Serge 96
        stdcall GetIntHandler, sb_irq_num
97
        call    SysMsgBoardNum
802 serge 98
 
2434 Serge 99
        jmp     .stop
802 serge 100
@@:
2434 Serge 101
        mov     esi, msgSucAtchIRQ
102
        call    SysMsgBoardStr
802 serge 103
end if
2434 Serge 104
        stdcall RegService, my_service, service_proc
105
        ret
802 serge 106
.stop:
2434 Serge 107
        call    sb_reset
802 serge 108
.exit:
109
 
110
if DEBUG
2434 Serge 111
        mov     esi, msgExit
112
        call    SysMsgBoardStr
802 serge 113
end if
114
 
2434 Serge 115
        xor     eax, eax
116
        ret
802 serge 117
endp
118
;-------------------------------------------------------------------------------
119
 
2434 Serge 120
handle     equ  IOCTL.handle
121
io_code    equ  IOCTL.io_code
122
input      equ  IOCTL.input
123
inp_size   equ  IOCTL.inp_size
124
output     equ  IOCTL.output
125
out_size   equ  IOCTL.out_size
802 serge 126
 
127
align 4
128
proc service_proc stdcall, ioctl:dword
2434 Serge 129
        mov     edi, [ioctl]
130
        mov     eax, [edi+io_code]
131
        cmp     eax, SRV_GETVERSION
132
        jne     @F
802 serge 133
 
2434 Serge 134
        mov     eax, [edi+output]
135
        cmp     [edi+out_size], 4
136
        jne     .fail
137
        mov     [eax], dword API_VERSION
138
        xor     eax, eax
139
        ret
802 serge 140
@@:
2434 Serge 141
        cmp     eax, DEV_PLAY
142
        jne     @f
802 serge 143
if DEBUG
2434 Serge 144
        mov     esi, msgPlay
145
        call    SysMsgBoardStr
802 serge 146
end if
2434 Serge 147
        call    sb_stop          ;to play smth new we must stop smth old
802 serge 148
 
2434 Serge 149
        call    pre_fill_data    ;fill first and second half of the buffer
150
        call    pre_fill_data    ;
802 serge 151
 
2434 Serge 152
        call    sb_set_dma       ;is it really needed here? Paranoia.
153
        call    sb_play
154
        xor     eax, eax          ;set maximum volume
155
        call    sb_set_master_vol
156
        xor     eax, eax
157
        ret
802 serge 158
;@@:                             ;all this commented stuff in service proc
159
;           cmp  eax,DEV_STOP    ;is never used. Mixer do this virtually,
160
;           jne  @f              ;e.g. instead of stopping driver it
161
;if DEBUG                        ;outputs silence
162
;           mov  esi,msgStop
163
;           call SysMsgBoardStr
164
;end if
165
;           call sb_stop
166
;           xor  eax,eax
167
;           ret
168
@@:
2434 Serge 169
        cmp     eax, DEV_CALLBACK
170
        jne     @f
802 serge 171
if DEBUG
2434 Serge 172
        mov     esi, msgCallback
173
        call    SysMsgBoardStr
802 serge 174
end if
2434 Serge 175
        mov     edi, [edi+input]
176
        mov     eax, [edi]
177
        mov     [callback], eax
802 serge 178
if DEBUG
2434 Serge 179
        call    SysMsgBoardNum
802 serge 180
end if
2434 Serge 181
        xor     eax, eax
182
        ret
802 serge 183
@@:
2434 Serge 184
        cmp     eax, DEV_SET_MASTERVOL;Serge asked me to unlock
185
        jne     @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it.
186
           ;It doesn't use it _in current version_ - but in the future...
802 serge 187
 
850 serge 188
if DEBUG
2434 Serge 189
        mov     esi, msgSetVol
190
        call    SysMsgBoardStr
850 serge 191
end if
2434 Serge 192
        mov     eax, [edi+input]
193
        mov     eax, [eax]
194
        call    sb_set_master_vol
195
        xor     eax, eax
196
        ret
850 serge 197
@@:
2434 Serge 198
        cmp     eax, DEV_GET_MASTERVOL
199
        jne     @F
850 serge 200
if DEBUG
2434 Serge 201
        mov     esi, msgGetVol
202
        call    SysMsgBoardStr
850 serge 203
end if
2434 Serge 204
        mov     eax, [edi+output]
205
        mov     edx, [sb_master_vol]
206
        mov     [eax], edx
207
        xor     eax, eax
208
        ret
850 serge 209
 
802 serge 210
.fail:
2434 Serge 211
        or      eax, -1
212
        ret
802 serge 213
endp
214
 
215
restore   handle
216
restore   io_code
217
restore   input
218
restore   inp_size
219
restore   output
220
restore   out_size
221
 
222
;-------------------------------------------------------------------------------
223
align 4
224
proc sb_irq
2434 Serge 225
        mov     edx, [sb_base_port];tell the DSP that we have processed IRQ
226
        add     dl, 0xF            ;0xF for 16 bit sound, 0xE for 8 bit sound
227
        in      al, dx             ;for non-stop sound
802 serge 228
 
229
pre_fill_data:
2434 Serge 230
        mov     eax, int_flip_flop
231
        not     dword[eax]
232
        mov     eax, [eax]
233
        test    eax, eax
234
        jns     .fill_second_half
802 serge 235
 
850 serge 236
if sb_buffer_size eq small_buffer
2434 Serge 237
        stdcall [callback], SB16Buffer0   ;for 32k buffer
850 serge 238
else if sb_buffer_size eq full_buffer
2434 Serge 239
        stdcall [callback], SB16Buffer0   ;for 64k buffer
240
        stdcall [callback], SB16Buffer1   ;for 64k buffer
850 serge 241
end if
2434 Serge 242
        xor     eax, eax
243
        not     eax
244
        ret
802 serge 245
 
246
.fill_second_half:
850 serge 247
if sb_buffer_size eq small_buffer
2434 Serge 248
        stdcall [callback], SB16Buffer1   ;for 32k buffer
850 serge 249
else if sb_buffer_size eq full_buffer
2434 Serge 250
        stdcall [callback], SB16Buffer2   ;for 64k buffer
251
        stdcall [callback], SB16Buffer3   ;for 64k buffer
850 serge 252
end if
2434 Serge 253
        xor     eax, eax
254
        not     eax
255
        ret
802 serge 256
endp
257
;-------------------------------------------------------------------------------
258
align 4
259
proc detect
260
.sb_detect_next_port:
261
if DEBUG
2434 Serge 262
        inc     dword[port_second_digit_num]
802 serge 263
end if
2434 Serge 264
        mov     edx, sb_base_port
265
        add     byte[edx], 10h
266
        cmp     byte[edx], 80h
267
        jbe     .sb_try_to_detect_at_specified_port
802 serge 268
;error - no SB card detected
269
.sb_not_found_err:
2434 Serge 270
        xor     eax, eax
271
        ret
802 serge 272
 
273
.sb_try_to_detect_at_specified_port:
2434 Serge 274
        call    sb_reset
275
        add     dl, 8
276
        mov     ecx, 100
802 serge 277
.sb_check_port:
2434 Serge 278
        in      al, dx
279
        test    al, al           ;is DSP port ready to be read?
280
        jns     .sb_port_not_ready
802 serge 281
 
2434 Serge 282
        sub     dl, 4
283
        in      al, dx           ;check for AAh response
284
        add     dl, 4
285
        cmp     al, 0xAA
286
        jne     .sb_port_not_ready
802 serge 287
.sb_card_found:
2434 Serge 288
        and     dl, 0xF0
289
        add     dl, 0xC
290
           sb_out 0xE1           ;get DSP version
291
        add     dl, 2
802 serge 292
@@:
2434 Serge 293
        in      al, dx
294
        test    al, al           ;is DSP port ready to be read?
295
        jns     @b
296
        sub     dl, 4
297
        in      al, dx           ;get major version
298
        ror     eax, 16
299
        add     dl, 4
802 serge 300
@@:
2434 Serge 301
        in      al, dx
302
        test    al, al           ;is DSP port ready to be read?
303
        jns     @b
304
        sub     dl, 4
305
        in      al, dx           ;get minor version
306
        xor     edx, edx
307
        mov     dl, 10
308
        div     dl
309
        ror     eax, 16
310
        xor     ah, ah
311
        mov     [sb_DSP_version_int], eax;for internal usage
802 serge 312
if DEBUG
2434 Serge 313
        add     [sb_DSP_version], eax
802 serge 314
end if
2434 Serge 315
        ret
802 serge 316
 
317
.sb_port_not_ready:
2434 Serge 318
        loop    .sb_check_port   ;100 retries (~100 microsec.)
319
        jmp     .sb_detect_next_port
802 serge 320
endp
321
;-------------------------------------------------------------------------------
322
if DEBUG
850 serge 323
proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
2434 Serge 324
        mov     ebx, eax
325
        mov     ecx, 8
326
        mov     esi, (number_to_out+1)
802 serge 327
.1:
2434 Serge 328
        mov     eax, ebx
329
        and     eax, 0xF
330
        add     al, '0'
331
        cmp     al, (10+'0')
332
        jb      @f
333
        add     al, ('A'-'0'-10)
802 serge 334
@@:
2434 Serge 335
        mov     [esi+ecx], al
336
        shr     ebx, 4
337
        loop    .1
338
        dec     esi
339
        call    SysMsgBoardStr
340
        ret
802 serge 341
endp
342
end if
343
;all initialized data place here
344
align 4
345
version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
346
 
2434 Serge 347
sb_base_port:
348
              dd 200h ;don't ask me why - see the code&docs
802 serge 349
 
350
sound_dma     dd sb_dma_num
351
 
352
;note that 4th DMA channel doesn't exist, it is used for cascade
353
;plugging the first DMA controler to the second
354
dma_table     db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
355
 
356
my_service    db 'SOUND',0  ;max 16 chars include zero
357
 
358
if DEBUG
359
number_to_out db '0x00000000',13,10,0
360
 
361
msgInit       db 'detecting hardware...',13,10,0
362
msgExit       db 'exiting... May be some problems found?',13,10,0
363
msgPlay       db 'start play',13,10,0
364
;msgStop       db 'stop play',13,10,0
365
msgCallback   db 'set_callback received from the mixer!',13,10
2434 Serge 366
              db 'callback handler is: ',0
802 serge 367
msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
2434 Serge 368
              db 'owner',39,'s handler: ',0
802 serge 369
msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
2434 Serge 370
              db ' as hardcoded',13,10,0
802 serge 371
msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
2434 Serge 372
              db 'Driver may work unstable',13,10,0
850 serge 373
msgSetVol     db 'DEV_SET_MASTERVOL call came',13,10,0
374
msgGetVol     db 'DEV_GET_MASTERVOL call came',13,10,0
802 serge 375
msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
376
;-------------------------------------------------------------------------------
377
msgDSPFound   db 'DSP found at port 2'
378
label port_second_digit_num dword at $
2434 Serge 379
              db '00h',13,10,'DSP version '
380
sb_DSP_version:
381
                db '0.00 - SB'
382
sb_DSP_description:
383
                    db 32,32,32,32,13,10,0
802 serge 384
;-------------------------------------------------------------------------------
385
end if
850 serge 386
 
387
section '.data' data readable writable align 16
802 serge 388
;all uninitialized data place here
850 serge 389
 
390
;pTempBuf          rd 1
391
 
2434 Serge 392
callback           rd 1
850 serge 393
 
2434 Serge 394
int_flip_flop      rd 1
850 serge 395
 
2434 Serge 396
sb_master_vol      rd 1
850 serge 397
 
398
sb_DSP_version_int rd 1