Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
;alpha version
9
 
10
format MS COFF
11
 
12
DEBUG       equ 1
13
 
14
 
15
include 'proc32.inc'
16
include 'imports.inc'
17
 
18
REMAP_IRQ   equ 0
19
 
20
;irq 0,1,2,8,12,13 недоступны
21
;               FEDCBA9876543210
22
VALID_IRQ   equ 1100111011111000b
23
ATTCH_IRQ   equ 0000111010101000b
24
 
25
IRQ_LINE    equ 0
26
 
27
CPU_FREQ    equ  2600d
28
 
29
BIT0  EQU 0x00000001
30
BIT1  EQU 0x00000002
31
BIT2  EQU 0x00000004
32
BIT3  EQU 0x00000008
33
BIT4  EQU 0x00000010
34
BIT5  EQU 0x00000020
35
BIT6  EQU 0x00000040
36
BIT7  EQU 0x00000080
37
BIT8  EQU 0x00000100
38
BIT9  EQU 0x00000200
39
BIT10 EQU 0x00000400
40
BIT11 EQU 0x00000800
41
BIT12 EQU 0x00001000
42
BIT13 EQU 0x00002000
43
BIT14 EQU 0x00004000
44
BIT15 EQU 0x00008000
45
BIT16 EQU 0x00010000
46
BIT17 EQU 0x00020000
47
BIT18 EQU 0x00040000
48
BIT19 EQU 0x00080000
49
BIT20 EQU 0x00100000
50
BIT21 EQU 0x00200000
51
BIT22 EQU 0x00400000
52
BIT23 EQU 0x00800000
53
BIT24 EQU 0x00100000
54
BIT25 EQU 0x02000000
55
BIT26 EQU 0x04000000
56
BIT27 EQU 0x08000000
57
BIT28 EQU 0x10000000
58
BIT29 EQU 0x20000000
59
BIT30 EQU 0x40000000
60
BIT31 EQU 0x80000000
61
 
62
 
63
PCM_OUT_BDL       equ  0x10      ; PCM out buffer descriptors list
64
PCM_OUT_CR_REG    equ  0x1b      ; PCM out Control Register
65
PCM_OUT_LVI_REG   equ  0x15      ; PCM last valid index
66
PCM_OUT_SR_REG    equ  0x16      ; PCM out Status register
67
PCM_OUT_PIV_REG   equ  0x1a
68
PCM_OUT_CIV_REG   equ  0x14      ; PCM out current index
69
 
70
PCM_IN_CR_REG     equ  0x0b      ; PCM in Control Register
71
MC_IN_CR_REG      equ  0x2b      ; MIC in Control Register
72
RR                equ  BIT1      ; reset registers.  Nukes all regs
73
 
74
CODEC_MASTER_VOL_REG            equ     0x02
75
CODEC_AUX_VOL                   equ     0x04    ;
76
CODEC_PCM_OUT_REG               equ     18h     ; PCM output volume
77
CODEC_EXT_AUDIO_REG             equ     28h     ; extended audio
78
CODEC_EXT_AUDIO_CTRL_REG        equ     2ah     ; extended audio control
79
CODEC_PCM_FRONT_DACRATE_REG     equ     2ch     ; PCM out sample rate
80
CODEC_PCM_SURND_DACRATE_REG     equ     2eh     ; surround sound sample rate
81
CODEC_PCM_LFE_DACRATE_REG       equ     30h     ; LFE sample rate
82
 
83
GLOB_CTRL      equ  0x2C        ;   Global Control
84
CTRL_STAT       equ  0x30        ;   Global Status
85
CTRL_CAS        equ  0x34        ;   Codec Access Semiphore
86
 
87
CAS_FLAG        equ  0x01        ;   Codec Access Semiphore Bit
88
 
89
CTRL_ST_CREADY  equ  BIT8+BIT9+BIT28 ;   Primary Codec Ready
90
 
91
CTRL_ST_RCS     equ  0x00008000  ;   Read Completion Status
92
 
93
CTRL_CNT_CRIE   equ  BIT4+BIT5+BIT6  ;   Codecs Resume Interrupt Enable
94
CTRL_CNT_AC_OFF equ  0x00000008  ;   ACLINK Off
95
CTRL_CNT_WARM   equ  0x00000004  ;   AC97 Warm Reset
96
CTRL_CNT_COLD   equ  0x00000002  ;   AC97 Cold Reset
97
CTRL_CNT_GIE    equ  0x00000001  ;   GPI Interrupt Enable
98
 
99
CODEC_REG_POWERDOWN   equ 0x26
100
CODEC_REG_ST          equ 0x26
101
 
102
DEV_PLAY              equ  1
103
DEV_STOP              equ  2
104
DEV_CALLBACK          equ  3
105
DEV_SET_BUFF          equ  4
106
DEV_NOTIFY            equ  5
107
DEV_SET_MASTERVOL     equ  6
108
DEV_GET_MASTERVOL     equ  7
109
DEV_GET_INFO          equ  8
110
 
111
struc AC_CNTRL              ;AC controller base class
112
{ .bus                dd ?
113
  .devfn              dd ?
114
 
115
  .vendor             dd ?
116
  .dev_id             dd ?
117
  .pci_cmd            dd ?
118
  .pci_stat           dd ?
119
 
120
  .codec_io_base      dd ?
121
  .codec_mem_base     dd ?
122
 
123
  .ctrl_io_base       dd ?
124
  .ctrl_mem_base      dd ?
125
  .cfg_reg            dd ?
126
  .int_line           dd ?
127
 
128
  .vendor_ids         dd ?    ;vendor id string
129
  .ctrl_ids           dd ?    ;hub id string
130
 
131
  .buffer             dd ?
132
 
133
  .notify_pos         dd ?
134
  .notify_task        dd ?
135
 
136
  .lvi_reg            dd ?
137
  .ctrl_setup         dd ?
138
  .user_callback      dd ?
139
  .codec_read16       dd ?
140
  .codec_write16      dd ?
141
 
142
  .ctrl_read8         dd ?
143
  .ctrl_read16        dd ?
144
  .ctrl_read32        dd ?
145
 
146
  .ctrl_write8        dd ?
147
  .ctrl_write16       dd ?
148
  .ctrl_write32       dd ?
149
}
150
 
151
struc CODEC                ;Audio Chip base class
152
{
153
  .chip_id            dd ?
154
  .flags              dd ?
155
  .status             dd ?
156
 
157
  .ac_vendor_ids      dd ?    ;ac vendor id string
158
  .chip_ids           dd ?    ;chip model string
159
 
160
  .shadow_flag        dd ?
161
                      dd ?
162
 
163
  .regs               dw ?     ; codec registers
164
  .reg_master_vol     dw ?     ;0x02
165
  .reg_aux_out_vol    dw ?     ;0x04
166
  .reg_mone_vol       dw ?     ;0x06
167
  .reg_master_tone    dw ?     ;0x08
168
  .reg_beep_vol       dw ?     ;0x0A
169
  .reg_phone_vol      dw ?     ;0x0C
170
  .reg_mic_vol        dw ?     ;0x0E
171
  .reg_line_in_vol    dw ?     ;0x10
172
  .reg_cd_vol         dw ?     ;0x12
173
  .reg_video_vol      dw ?     ;0x14
174
  .reg_aux_in_vol     dw ?     ;0x16
175
  .reg_pcm_out_vol    dw ?     ;0x18
176
  .reg_rec_select     dw ?     ;0x1A
177
  .reg_rec_gain       dw ?     ;0x1C
178
  .reg_rec_gain_mic   dw ?     ;0x1E
179
  .reg_gen            dw ?     ;0x20
180
  .reg_3d_ctrl        dw ?     ;0X22
181
  .reg_page           dw ?     ;0X24
182
  .reg_powerdown      dw ?     ;0x26
183
  .reg_ext_audio      dw ?     ;0x28
184
  .reg_ext_st         dw ?     ;0x2a
185
  .reg_pcm_front_rate dw ?     ;0x2c
186
  .reg_pcm_surr_rate  dw ?     ;0x2e
187
  .reg_lfe_rate       dw ?     ;0x30
188
  .reg_pcm_in_rate    dw ?     ;0x32
189
                      dw ?     ;0x34
190
  .reg_cent_lfe_vol   dw ?     ;0x36
191
  .reg_surr_vol       dw ?     ;0x38
192
  .reg_spdif_ctrl     dw ?     ;0x3A
193
                      dw ?     ;0x3C
194
                      dw ?     ;0x3E
195
                      dw ?     ;0x40
196
                      dw ?     ;0x42
197
                      dw ?     ;0x44
198
                      dw ?     ;0x46
199
                      dw ?     ;0x48
200
                      dw ?     ;0x4A
201
                      dw ?     ;0x4C
202
                      dw ?     ;0x4E
203
                      dw ?     ;0x50
204
                      dw ?     ;0x52
205
                      dw ?     ;0x54
206
                      dw ?     ;0x56
207
                      dw ?     ;0x58
208
                      dw ?     ;0x5A
209
                      dw ?     ;0x5C
210
                      dw ?     ;0x5E
211
  .reg_page_0         dw ?     ;0x60
212
  .reg_page_1         dw ?     ;0x62
213
  .reg_page_2         dw ?     ;0x64
214
  .reg_page_3         dw ?     ;0x66
215
  .reg_page_4         dw ?     ;0x68
216
  .reg_page_5         dw ?     ;0x6A
217
  .reg_page_6         dw ?     ;0x6C
218
  .reg_page_7         dw ?     ;0x6E
219
                      dw ?     ;0x70
220
                      dw ?     ;0x72
221
                      dw ?     ;0x74
222
                      dw ?     ;0x76
223
                      dw ?     ;0x78
224
                      dw ?     ;0x7A
225
  .reg_vendor_id_1    dw ?     ;0x7C
226
  .reg_vendor_id_2    dw ?     ;0x7E
227
 
228
 
229
  .reset              dd ?    ;virual
230
  .set_master_vol     dd ?
231
}
232
 
233
struc CTRL_INFO
234
{   .pci_cmd        dd  ?
235
    .irq            dd  ?
236
    .glob_cntrl     dd  ?
237
    .glob_sta       dd  ?
238
    .codec_io_base  dd  ?
239
    .ctrl_io_base   dd  ?
240
    .codec_mem_base dd  ?
241
    .ctrl_mem_base  dd  ?
242
    .codec_id       dd  ?
243
}
244
 
245
struc IOCTL
246
{  .handle           dd ?
247
   .io_code          dd ?
248
   .input            dd ?
249
   .inp_size         dd ?
250
   .output           dd ?
251
   .out_size         dd ?
252
}
253
 
254
virtual at 0
255
  IOCTL IOCTL
256
end virtual
257
 
258
EVENT_NOTIFY          equ 0x00000200
259
 
260
OS_BASE         equ 0x80000000
261
SLOT_BASE       equ OS_BASE+0x0080000
262
new_app_base    equ 0
263
 
264
public START
265
public service_proc
266
public version
267
 
268
section '.flat' code readable align 16
269
 
270
proc START stdcall, state:dword
271
 
272
        cmp     [state], 1
273
        jne     .stop
274
 
275
     if DEBUG
276
        mov     esi, msgDetect
277
        call    SysMsgBoardStr
278
     end if
279
 
280
        call    detect_controller
281
        test    eax, eax
282
        jz      .fail
283
 
284
     if DEBUG
285
        mov     esi, [ctrl.vendor_ids]
286
        call    SysMsgBoardStr
287
        mov     esi, [ctrl.ctrl_ids]
288
        call    SysMsgBoardStr
289
 
290
     end if
291
        call    init_controller
292
        test    eax, eax
293
        jz      .fail
294
 
295
        jmp     .fail     ;force fail
296
 
297
     if DEBUG
298
        mov     esi, msgInitCodec
299
        call    SysMsgBoardStr
300
     end if
301
 
302
        call    init_codec
303
        test    eax, eax
304
        jz      .fail
305
 
306
     if DEBUG
307
        mov     esi, [codec.ac_vendor_ids]
308
        call    SysMsgBoardStr
309
 
310
        mov     esi, [codec.chip_ids]
311
        call    SysMsgBoardStr
312
     end if
313
 
314
        call    reset_controller
315
        call    setup_codec
316
 
317
        mov     esi, msgPrimBuff
318
        call    SysMsgBoardStr
319
 
320
        call    create_primary_buff
321
 
322
        mov     eax, VALID_IRQ
323
        mov     ebx, [ctrl.int_line]
324
        mov     esi, msgInvIRQ
325
        bt      eax, ebx
326
        jnc     .fail
327
        mov     eax, ATTCH_IRQ
328
        mov     esi, msgAttchIRQ
329
        bt      eax, ebx
330
        jnc     .fail
331
 
332
        stdcall AttachIntHandler, ebx, ac97_irq, dword 0
333
        stdcall RegService, sz_sound_srv, service_proc
334
        ret
335
.fail:
336
     if DEBUG
337
        mov     esi, msgFail
338
        call    SysMsgBoardStr
339
     end if
340
        xor     eax, eax
341
        ret
342
.stop:
343
        call    stop
344
        xor     eax, eax
345
        ret
346
endp
347
 
348
handle     equ  IOCTL.handle
349
io_code    equ  IOCTL.io_code
350
input      equ  IOCTL.input
351
inp_size   equ  IOCTL.inp_size
352
output     equ  IOCTL.output
353
out_size   equ  IOCTL.out_size
354
 
355
align 4
356
proc service_proc stdcall, ioctl:dword
357
 
358
        mov     edi, [ioctl]
359
        mov     eax, [edi+io_code]
360
        cmp     eax, DEV_PLAY
361
        jne     @F
362
     if DEBUG
363
        mov     esi, msgPlay
364
        call    SysMsgBoardStr
365
     end if
366
        call    play
367
        ret
368
@@:
369
        cmp     eax, DEV_STOP
370
        jne     @F
371
     if DEBUG
372
        mov     esi, msgStop
373
        call    SysMsgBoardStr
374
     end if
375
        call    stop
376
        ret
377
@@:
378
        cmp     eax, DEV_CALLBACK
379
        jne     @F
380
        mov     ebx, [edi+input]
381
        stdcall set_callback, [ebx]
382
        ret
383
@@:
384
        cmp     eax, DEV_SET_MASTERVOL
385
        jne     @F
386
        mov     eax, [edi+input]
387
        mov     eax, [eax]
388
        call    set_master_vol      ;eax= vol
389
        ret
390
@@:
391
        cmp     eax, DEV_GET_MASTERVOL
392
        jne     @F
393
        mov     ebx, [edi+output]
394
        stdcall get_master_vol, ebx
395
        ret
396
;@@:
397
;           cmp eax, DEV_GET_INFO
398
;           jne @F
399
;           mov ebx, [edi+output]
400
;           stdcall get_dev_info, ebx
401
;           ret
402
@@:
403
.fail:
404
        or      eax, -1
405
        ret
406
endp
407
 
408
restore   handle
409
restore   io_code
410
restore   input
411
restore   inp_size
412
restore   output
413
restore   out_size
414
 
415
 
416
align 4
417
proc ac97_irq
418
 
419
;     if DEBUG
420
;           mov esi, msgIRQ
421
;           call SysMsgBoardStr
422
;     end if
423
 
424
 
425
        cmp     [ctrl.user_callback], 0
426
        je      @f
427
 
428
        stdcall [ctrl.user_callback], ebx
429
@@:
430
        ret
431
 
432
.skip:
433
        mov     edx, PCM_OUT_CR_REG
434
        mov     ax, 0x11              ;0x1D
435
        call    [ctrl.ctrl_write8]
436
        ret
437
endp
438
 
439
align 4
440
proc create_primary_buff
441
 
442
        stdcall KernelAlloc, 0x10000
443
        mov     [ctrl.buffer], eax
444
 
445
        mov     edi, eax
446
        mov     ecx, 0x10000/4
447
        xor     eax, eax
448
        cld
449
        rep stosd
450
 
451
        mov     eax, [ctrl.buffer]
452
        call    GetPgAddr
453
 
454
        mov     ebx, 0xC0002000
455
        mov     ecx, 4
456
        mov     edi, pcmout_bdl
457
@@:
458
        mov     [edi], eax
459
        mov     [edi+4], ebx
460
 
461
        mov     [edi+32], eax
462
        mov     [edi+4+32], ebx
463
 
464
        mov     [edi+64], eax
465
        mov     [edi+4+64], ebx
466
 
467
        mov     [edi+96], eax
468
        mov     [edi+4+96], ebx
469
 
470
        mov     [edi+128], eax
471
        mov     [edi+4+128], ebx
472
 
473
        mov     [edi+160], eax
474
        mov     [edi+4+160], ebx
475
 
476
        mov     [edi+192], eax
477
        mov     [edi+4+192], ebx
478
 
479
        mov     [edi+224], eax
480
        mov     [edi+4+224], ebx
481
 
482
        add     eax, 0x4000
483
        add     edi, 8
484
        loop    @B
485
 
486
        mov     edi, buff_list
487
        mov     eax, [ctrl.buffer]
488
        mov     ecx, 4
489
@@:
490
        mov     [edi], eax
491
        mov     [edi+16], eax
492
        mov     [edi+32], eax
493
        mov     [edi+48], eax
494
        mov     [edi+64], eax
495
        mov     [edi+80], eax
496
        mov     [edi+96], eax
497
        mov     [edi+112], eax
498
 
499
        add     eax, 0x4000
500
        add     edi, 4
501
        loop    @B
502
 
503
        mov     eax, pcmout_bdl
504
        mov     ebx, eax
505
        call    GetPgAddr     ;eax
506
        and     ebx, 0xFFF
507
        add     eax, ebx
508
 
509
        mov     edx, PCM_OUT_BDL
510
        call    [ctrl.ctrl_write32]
511
 
512
        mov     eax, 16
513
        mov     [ctrl.lvi_reg], eax
514
        mov     edx, PCM_OUT_LVI_REG
515
        call    [ctrl.ctrl_write8]
516
        ret
517
endp
518
 
519
align 4
520
proc detect_controller
521
         locals
522
           last_bus dd ?
523
           bus      dd ?
524
           devfn    dd ?
525
         endl
526
 
527
        xor     eax, eax
528
        mov     [bus], eax
529
        inc     eax
530
        call    PciApi
531
        cmp     eax, -1
532
        je      .err
533
 
534
        mov     [last_bus], eax
535
 
536
.next_bus:
537
        and     [devfn], 0
538
.next_dev:
539
        stdcall PciRead32, [bus], [devfn], dword 0
540
        test    eax, eax
541
        jz      .next
542
        cmp     eax, -1
543
        je      .next
544
 
545
        mov     edi, devices
546
@@:
547
        mov     ebx, [edi]
548
        test    ebx, ebx
549
        jz      .next
550
 
551
        cmp     eax, ebx
552
        je      .found
553
        add     edi, 12
554
        jmp     @B
555
 
556
.next:
557
        inc     [devfn]
558
        cmp     [devfn], 256
559
        jb      .next_dev
560
        mov     eax, [bus]
561
        inc     eax
562
        mov     [bus], eax
563
        cmp     eax, [last_bus]
564
        jna     .next_bus
565
        xor     eax, eax
566
        ret
567
.found:
568
        mov     ebx, [bus]
569
        mov     [ctrl.bus], ebx
570
 
571
        mov     ecx, [devfn]
572
        mov     [ctrl.devfn], ecx
573
 
574
        mov     edx, eax
575
        and     edx, 0xFFFF
576
        mov     [ctrl.vendor], edx
577
        shr     eax, 16
578
        mov     [ctrl.dev_id], eax
579
 
580
        mov     ebx, [edi+4]
581
        mov     [ctrl.ctrl_ids], ebx
582
        mov     esi, [edi+8]
583
        mov     [ctrl.ctrl_setup], esi
584
 
585
        cmp     ebx, 0x1274
586
        jne     @F
587
        mov     [ctrl.vendor_ids], msgEnsoniq
588
        ret
589
@@:
590
        mov     [ctrl.vendor_ids], 0    ;something  wrong ?
591
        ret
592
.err:
593
        xor     eax, eax
594
        ret
595
endp
596
 
597
align 4
598
proc init_controller
599
 
600
        mov     esi, msgPCIcmd
601
        call    SysMsgBoardStr
602
 
603
        stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
604
        mov     ebx, eax
605
        and     eax, 0xFFFF
606
        mov     [ctrl.pci_cmd], eax
607
        shr     ebx, 16
608
        mov     [ctrl.pci_stat], ebx
609
 
610
        call    dword2str
611
        call    SysMsgBoardStr
612
 
613
        mov     esi, msgIObase
614
        call    SysMsgBoardStr
615
 
616
        stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
617
;           and eax, -16
618
        mov     [ctrl.ctrl_io_base], eax
619
 
620
        call    dword2str
621
        call    SysMsgBoardStr
622
 
623
        mov     esi, msgIRQline
624
        call    SysMsgBoardStr
625
 
626
        stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
627
        and     eax, 0xFF
628
        mov     [ctrl.int_line], eax
629
 
630
        call    dword2str
631
        call    SysMsgBoardStr
632
 
633
        call    [ctrl.ctrl_setup]
634
        xor     eax, eax
635
        inc     eax
636
        ret
637
endp
638
 
639
align 4
640
proc set_ICH
641
        mov     [ctrl.codec_read16], codec_io_r16    ;virtual
642
        mov     [ctrl.codec_write16], codec_io_w16   ;virtual
643
 
644
        mov     [ctrl.ctrl_read8 ], ctrl_io_r8      ;virtual
645
        mov     [ctrl.ctrl_read16], ctrl_io_r16      ;virtual
646
        mov     [ctrl.ctrl_read32], ctrl_io_r32      ;virtual
647
 
648
        mov     [ctrl.ctrl_write8 ], ctrl_io_w8     ;virtual
649
        mov     [ctrl.ctrl_write16], ctrl_io_w16     ;virtual
650
        mov     [ctrl.ctrl_write32], ctrl_io_w32     ;virtual
651
        ret
652
endp
653
 
654
align 4
655
proc reset_controller
656
 
657
        xor     eax, eax
658
        mov     edx, PCM_IN_CR_REG
659
        call    [ctrl.ctrl_write8]
660
 
661
        mov     edx, PCM_OUT_CR_REG
662
        call    [ctrl.ctrl_write8]
663
 
664
        mov     edx, MC_IN_CR_REG
665
        call    [ctrl.ctrl_write8]
666
 
667
        mov     eax, RR
668
        mov     edx, PCM_IN_CR_REG
669
        call    [ctrl.ctrl_write8]
670
 
671
        mov     edx, PCM_OUT_CR_REG
672
        call    [ctrl.ctrl_write8]
673
 
674
        mov     edx, MC_IN_CR_REG
675
        call    [ctrl.ctrl_write8]
676
        ret
677
endp
678
 
679
align 4
680
proc init_codec
681
         locals
682
           counter dd ?
683
         endl
684
 
685
        mov     esi, msgControl
686
        call    SysMsgBoardStr
687
 
688
        mov     edx, GLOB_CTRL
689
        call    [ctrl.ctrl_read32]
690
        call    dword2str
691
        call    SysMsgBoardStr
692
 
693
        mov     esi, msgStatus
694
        call    SysMsgBoardStr
695
 
696
        mov     edx, CTRL_STAT
697
        call    [ctrl.ctrl_read32]
698
 
699
        call    dword2str
700
        call    SysMsgBoardStr
701
 
702
        test    eax, CTRL_ST_CREADY
703
        jnz     .ready
704
 
705
        call    reset_codec
706
        and     eax, eax
707
        jz      .err
708
 
709
        xor     edx, edx    ;ac_reg_0
710
        call    [ctrl.codec_write16]
711
 
712
        xor     eax, eax
713
        mov     edx, CODEC_REG_POWERDOWN
714
        call    [ctrl.codec_write16]
715
 
716
        mov     [counter], 200    ; total 200*5 ms = 1s
717
.wait:
718
        mov     edx, CODEC_REG_POWERDOWN
719
        call    [ctrl.codec_read16]
720
        and     eax, 0x0F
721
        cmp     eax, 0x0F
722
        jz      .ready
723
 
724
        mov     eax, 5000  ; wait 5 ms
725
        call    StallExec
726
        sub     [counter] , 1
727
        jnz     .wait
728
.err:
729
        xor     eax, eax       ; timeout error
730
        ret
731
.ready:
732
        call    detect_codec
733
 
734
        xor     eax, eax
735
        inc     eax
736
        ret
737
endp
738
 
739
align 4
740
proc reset_codec
741
        mov     edx, GLOB_CTRL
742
        call    [ctrl.ctrl_read32]
743
 
744
        test    eax, 0x02
745
        jz      .cold
746
 
747
        call    warm_reset
748
        jnc     .ok
749
.cold:
750
        call    cold_reset
751
        jnc     .ok
752
 
753
     if DEBUG
754
        mov     esi, msgCFail
755
        call    SysMsgBoardStr
756
     end if
757
        xor     eax, eax    ; timeout error
758
        ret
759
.ok:
760
     if DEBUG
761
        mov     esi, msgResetOk
762
        call    SysMsgBoardStr
763
     end if
764
 
765
        xor     eax, eax
766
        inc     eax
767
        ret
768
endp
769
 
770
align 4
771
proc warm_reset
772
           locals
773
             counter dd ?
774
           endl
775
 
776
        mov     eax, 0x06
777
        mov     edx, GLOB_CTRL
778
        call    [ctrl.ctrl_write32]
779
 
780
     if DEBUG
781
        mov     esi, msgWarm
782
        call    SysMsgBoardStr
783
     end if
784
 
785
        mov     [counter], 10      ; total 10*100 ms = 1s
786
.wait:
787
        mov     eax, 100000        ; wait 100 ms
788
        call    StallExec
789
 
790
        mov     edx, GLOB_CTRL
791
        call    [ctrl.ctrl_read32]
792
        test    eax, 4
793
        jz      .ok
794
        sub     [counter], 1
795
        jnz     .wait
796
 
797
     if DEBUG
798
        mov     esi, msgWRFail
799
        call    SysMsgBoardStr
800
     end if
801
 
802
        stc
803
        ret
804
.ok:
805
        mov     edx, CTRL_STAT
806
        call    [ctrl.ctrl_read32]
807
        and     eax, CTRL_ST_CREADY
808
        jz      .fail
809
        clc
810
        ret
811
.fail:
812
        stc
813
        ret
814
endp
815
 
816
align 4
817
proc cold_reset
818
           locals
819
             counter dd ?
820
           endl
821
 
822
        xor     eax, eax
823
        mov     edx, GLOB_CTRL
824
        call    [ctrl.ctrl_write32]
825
 
826
     if DEBUG
827
        mov     esi, msgCold
828
        call    SysMsgBoardStr
829
     end if
830
 
831
        mov     eax, 1000000       ; wait 1 s
832
        call    StallExec
833
 
834
        mov     eax, 2
835
        mov     edx, GLOB_CTRL
836
        call    [ctrl.ctrl_write32]
837
 
838
        mov     [counter], 10      ; total 10*100 ms = 1s
839
.wait:
840
        mov     eax, 100000        ; wait 100 ms
841
        call    StallExec
842
 
843
        mov     edx, GLOB_CTRL
844
        call    [ctrl.ctrl_read32]
845
        test    eax, 4
846
        jz      .ok
847
        sub     [counter], 1
848
        jnz     .wait
849
 
850
     if DEBUG
851
        mov     esi, msgCRFail
852
        call    SysMsgBoardStr
853
     end if
854
        stc
855
        ret
856
.ok:
857
        mov     edx, CTRL_STAT
858
        call    [ctrl.ctrl_read32]
859
        and     eax, CTRL_ST_CREADY
860
        jz      .fail
861
        clc
862
        ret
863
.fail:
864
        stc
865
        ret
866
endp
867
 
868
align 4
869
play:
870
        mov     eax, 16
871
        mov     [ctrl.lvi_reg], eax
872
        mov     edx, PCM_OUT_LVI_REG
873
        call    [ctrl.ctrl_write8]
874
 
875
        mov     edx, PCM_OUT_CR_REG
876
        mov     ax, 0x1D
877
        call    [ctrl.ctrl_write8]
878
        xor     eax, eax
879
        ret
880
 
881
align 4
882
stop:
883
        mov     edx, PCM_OUT_CR_REG
884
        mov     ax, 0x0
885
        call    [ctrl.ctrl_write8]
886
 
887
        mov     ax, 0x1c
888
        mov     edx, PCM_OUT_SR_REG
889
        call    [ctrl.ctrl_write16]
890
        xor     eax, eax
891
        ret
892
 
893
align 4
894
proc get_dev_info stdcall, p_info:dword
895
           virtual at esi
896
             CTRL_INFO CTRL_INFO
897
           end virtual
898
 
899
        mov     esi, [p_info]
900
        mov     eax, [ctrl.int_line]
901
        mov     ebx, [ctrl.codec_io_base]
902
        mov     ecx, [ctrl.ctrl_io_base]
903
        mov     edx, [ctrl.codec_mem_base]
904
        mov     edi, [ctrl.ctrl_mem_base]
905
 
906
        mov     [CTRL_INFO.irq], eax
907
        mov     [CTRL_INFO.codec_io_base], ebx
908
        mov     [CTRL_INFO.ctrl_io_base], ecx
909
        mov     [CTRL_INFO.codec_mem_base], edx
910
        mov     [CTRL_INFO.ctrl_mem_base], edi
911
 
912
        mov     eax, [codec.chip_id]
913
        mov     [CTRL_INFO.codec_id], eax
914
 
915
        mov     edx, GLOB_CTRL
916
        call    [ctrl.ctrl_read32]
917
        mov     [CTRL_INFO.glob_cntrl], eax
918
 
919
        mov     edx, CTRL_STAT
920
        call    [ctrl.ctrl_read32]
921
        mov     [CTRL_INFO.glob_sta], eax
922
 
923
        mov     ebx, [ctrl.pci_cmd]
924
        mov     [CTRL_INFO.pci_cmd], ebx
925
        ret
926
endp
927
 
928
align 4
929
proc set_callback stdcall, handler:dword
930
        mov     eax, [handler]
931
        mov     [ctrl.user_callback], eax
932
        ret
933
endp
934
 
935
align 4
936
proc codec_read stdcall, ac_reg:dword      ; reg = edx, reval = eax
937
 
938
        mov     edx, [ac_reg]
939
 
940
        mov     ebx, edx
941
        shr     ebx, 1
942
        bt      [codec.shadow_flag], ebx
943
        jc      .use_shadow
944
 
945
        call    [ctrl.codec_read16]  ;change edx !!!
946
        mov     ecx, eax
947
 
948
        mov     edx, CTRL_STAT
949
        call    [ctrl.ctrl_read32]
950
        test    eax, CTRL_ST_RCS
951
        jz      .read_ok
952
 
953
        mov     edx, CTRL_STAT
954
        call    [ctrl.ctrl_write32]
955
        xor     eax, eax
956
        not     eax             ;timeout
957
        ret
958
.read_ok:
959
        mov     edx, [ac_reg]
960
        mov     [codec.regs+edx], cx
961
        bts     [codec.shadow_flag], ebx
962
        mov     eax, ecx
963
        ret
964
.use_shadow:
965
        movzx   eax, word [codec.regs+edx]
966
        ret
967
endp
968
 
969
align 4
970
proc codec_write stdcall, ac_reg:dword
971
        push    eax
972
        call    check_semafore
973
        and     eax, eax
974
        jz      .err
975
        pop     eax
976
 
977
        mov     esi, [ac_reg]
978
        mov     edx, esi
979
        call    [ctrl.codec_write16]
980
        mov     [codec.regs+esi], ax
981
        shr     esi, 1
982
        bts     [codec.shadow_flag], esi
983
        ret
984
.err:
985
        pop     eax
986
        ret
987
endp
988
 
989
align 4
990
proc codec_check_ready
991
 
992
        mov     edx, CTRL_ST
993
        call    [ctrl.ctrl_read32]
994
        and     eax, CTRL_ST_CREADY
995
        jz      .not_ready
996
 
997
        xor     eax, wax
998
        inc     eax
999
        ret
1000
.not_ready:
1001
        xor     eax, eax
1002
        ret
1003
endp
1004
 
1005
align 4
1006
proc check_semafore
1007
           local counter:DWORD
1008
 
1009
        mov     [counter], 100
1010
.l1:
1011
        mov     edx, CTRL_CAS
1012
        call    [ctrl.ctrl_read8]
1013
        and     eax, CAS_FLAG
1014
        jz      .ok
1015
 
1016
        mov     eax, 1
1017
        call    StallExec
1018
        sub     [counter], 1
1019
        jnz     .l1
1020
        xor     eax, eax
1021
        ret
1022
align 4
1023
.ok:
1024
        xor     eax, eax
1025
        inc     eax
1026
        ret
1027
endp
1028
 
1029
align 4
1030
proc StallExec
1031
        push    ecx
1032
        push    edx
1033
        push    ebx
1034
        push    eax
1035
 
1036
        mov     ecx, CPU_FREQ
1037
        mul     ecx
1038
        mov     ebx, eax      ;low
1039
        mov     ecx, edx      ;high
1040
        rdtsc
1041
        add     ebx, eax
1042
        adc     ecx, edx
1043
@@:
1044
        rdtsc
1045
        sub     eax, ebx
1046
        sbb     edx, ecx
1047
        js      @B
1048
 
1049
        pop     eax
1050
        pop     ebx
1051
        pop     edx
1052
        pop     ecx
1053
        ret
1054
endp
1055
 
1056
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1057
;          CONTROLLER IO functions
1058
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1059
 
1060
align 4
1061
codec_io_r16:
1062
        add     edx, [ctrl.codec_io_base]
1063
        in      ax, dx
1064
        ret
1065
 
1066
align 4
1067
codec_io_w16:
1068
        add     edx, [ctrl.codec_io_base]
1069
        out     dx, ax
1070
        ret
1071
 
1072
align 4
1073
ctrl_io_r8:
1074
        add     edx, [ctrl.ctrl_io_base]
1075
        in      al, dx
1076
        ret
1077
 
1078
align 4
1079
ctrl_io_r16:
1080
        add     edx, [ctrl.ctrl_io_base]
1081
        in      ax, dx
1082
        ret
1083
 
1084
align 4
1085
ctrl_io_r32:
1086
        add     edx, [ctrl.ctrl_io_base]
1087
        in      eax, dx
1088
        ret
1089
 
1090
align 4
1091
ctrl_io_w8:
1092
        add     edx, [ctrl.ctrl_io_base]
1093
        out     dx, al
1094
        ret
1095
 
1096
align 4
1097
ctrl_io_w16:
1098
        add     edx, [ctrl.ctrl_io_base]
1099
        out     dx, ax
1100
        ret
1101
 
1102
align 4
1103
ctrl_io_w32:
1104
        add     edx, [ctrl.ctrl_io_base]
1105
        out     dx, eax
1106
        ret
1107
 
1108
 
1109
align 4
1110
dword2str:
1111
        mov     esi, hex_buff
1112
        mov     ecx, -8
1113
@@:
1114
        rol     eax, 4
1115
        mov     ebx, eax
1116
        and     ebx, 0x0F
1117
        mov     bl, [ebx+hexletters]
1118
        mov     [8+esi+ecx], bl
1119
        inc     ecx
1120
        jnz     @B
1121
        ret
1122
 
1123
hexletters   db '0123456789ABCDEF'
1124
hex_buff     db 8 dup(0),13,10,0
1125
 
1126
 
1127
include "codec.inc"
1128
 
1129
align 4
1130
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH
1131
        dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH
1132
        dd 0    ;terminator
1133
 
1134
version      dd 0x00040004
1135
 
1136
msgEnsoniq   db 'Ensonic 1371',13,10,0
1137
msgVibra128  db 'Sound Blaster AudioPCI Vibra 128',13,10,0
1138
 
1139
sz_sound_srv db 'SOUND',0
1140
 
1141
msgDetect    db 'detect hardware...',13,10,0
1142
msgFail      db 'device not found',13,10,0
1143
msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
1144
msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
1145
msgPlay      db 'start play', 13,10,0
1146
msgStop      db 'stop play',  13,10,0
1147
msgNotify    db 'call notify',13,10,0
1148
msgIRQ       db 'AC97 IRQ', 13,10,0
1149
msgInitCtrl  db 'init controller',13,10,0
1150
msgInitCodec db 'init codec',13,10,0
1151
msgPrimBuff  db 'create primary buffer',13,10,0
1152
msgReg       db 'set service handler',13,10,0
1153
msgOk        db 'service installed',13,10,0
1154
msgCold      db 'cold reset',13,10,0
1155
msgWarm      db 'warm reset',13,10,0
1156
msgWRFail    db 'warm reset failed',13,10,0
1157
msgCRFail    db 'cold reset failed',13,10,0
1158
msgCFail     db 'codec not ready',13,10,0
1159
msgResetOk   db 'reset complete',13,10,0
1160
msgStatus    db 'global status   ',0
1161
msgControl   db 'global control  ',0
1162
msgPCIcmd    db 'PCI command     ',0
1163
msgIObase    db 'IO base         ',0
1164
msgIRQline   db 'IRQ line        ',0
1165
 
1166
section '.data' data readable writable align 16
1167
 
1168
pcmout_bdl       rq 32
1169
buff_list        rd 32
1170
 
1171
codec CODEC
1172
ctrl AC_CNTRL
1173
 
1174
lpc_bus  rd 1
1175
civ_val  rd 1
1176