Subversion Repositories Kolibri OS

Rev

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

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