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