Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
384 mikedld 1
 
2
3
 
4
include 'imports.inc'
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 ?
98
  .devfn              dd ?
99
100
 
101
  .dev_id             dd ?
102
  .pci_cmd            dd ?
103
  .pci_stat           dd ?
104
105
 
106
  .codec_mem_base     dd ?
107
108
 
109
  .ctrl_mem_base      dd ?
110
  .cfg_reg            dd ?
111
  .int_line           dd ?
112
113
 
114
  .ctrl_ids           dd ?    ;hub id string
115
116
 
117
118
 
119
  .notify_task        dd ?
120
121
 
122
  .ctrl_setup         dd ?
123
  .user_callback      dd ?
124
  .codec_read16       dd ?
125
  .codec_write16      dd ?
126
127
 
128
  .ctrl_read16        dd ?
129
  .ctrl_read32        dd ?
130
131
 
132
  .ctrl_write16       dd ?
133
  .ctrl_write32       dd ?
134
}
135
136
 
137
{
138
  .chip_id            dd ?
139
  .flags              dd ?
140
  .status             dd ?
141
142
 
143
  .chip_ids           dd ?    ;chip model string
144
145
 
146
                      dd ?
147
148
 
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
213
 
214
 
215
  .set_master_vol     dd ?
216
}
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
SLOT_BASE          equ OS_BASE+0x0080000
247
new_app_base       equ 0x80000000
248
249
 
250
public service_proc
251
public version
252
253
 
254
255
 
256
257
 
258
           jne .stop
259
260
 
261
           mov esi, msgInit
262
           call SysMsgBoardStr
263
     end if
264
265
 
266
           test eax, eax
267
           jz .fail
268
269
 
270
           mov esi,[ctrl.vendor_ids]
271
           call SysMsgBoardStr
272
           mov  esi, [ctrl.ctrl_ids]
273
           call SysMsgBoardStr
274
     end if
275
276
 
277
           test eax, eax
278
           jz .fail
279
280
 
281
           mov esi, msgInitCodec
282
           call SysMsgBoardStr
283
     end if
284
285
 
286
           test eax, eax
287
           jz .fail
288
289
 
290
           mov esi, [codec.ac_vendor_ids]
291
           call SysMsgBoardStr
292
293
 
294
           call SysMsgBoardStr
295
     end if
296
297
 
298
           call setup_codec
299
300
 
301
           call SysMsgBoardStr
302
303
 
304
305
 
306
307
 
308
309
 
310
           call SysMsgBoardStr
311
           ret
312
.fail:
313
   if DEBUG
314
           mov esi, msgFail
315
           call SysMsgBoardStr
316
   end if
317
           xor eax, eax
318
           ret
319
.stop:
320
           call stop
321
           xor eax, eax
322
           ret
323
endp
324
325
 
326
io_code    equ  IOCTL.io_code
327
input      equ  IOCTL.input
328
inp_size   equ  IOCTL.inp_size
329
output     equ  IOCTL.output
330
out_size   equ  IOCTL.out_size
331
332
 
333
proc service_proc stdcall, ioctl:dword
334
335
 
336
           mov eax, [edi+io_code]
337
           cmp eax, DEV_PLAY
338
           jne @F
339
     if DEBUG
340
           mov esi, msgPlay
341
           call SysMsgBoardStr
342
     end if
343
           call play
344
           ret
345
@@:
346
           cmp eax, DEV_STOP
347
           jne @F
348
     if DEBUG
349
           mov esi, msgStop
350
           call SysMsgBoardStr
351
     end if
352
           call stop
353
           ret
354
@@:
355
           cmp eax, DEV_CALLBACK
356
           jne @F
357
           mov ebx, [edi+input]
358
           stdcall set_callback, [ebx]
359
           ret
360
@@:
361
           cmp eax, DEV_SET_MASTERVOL
362
           jne @F
363
           mov eax, [edi+input]
364
           mov eax, [eax]
365
           call set_master_vol      ;eax= vol
366
           ret
367
@@:
368
           cmp eax, DEV_GET_MASTERVOL
369
           jne @F
370
           mov ebx, [edi+output]
371
           add ebx, new_app_base
372
           stdcall get_master_vol, ebx
373
           ret
374
@@:
375
           cmp eax, DEV_GET_INFO
376
           jne @F
377
           mov ebx, [edi+output]
378
           stdcall get_dev_info, ebx
379
           ret
380
@@:
381
.fail:
382
           or eax, -1
383
           ret
384
endp
385
386
 
387
restore   io_code
388
restore   input
389
restore   inp_size
390
restore   output
391
restore   out_size
392
393
 
394
proc ac97_irq
395
396
 
397
;           mov esi, msgIRQ
398
;           call SysMsgBoardStr
399
;     end if
400
401
 
402
           mov al, 0x10
403
           call [ctrl.ctrl_write8]
404
405
 
406
           mov edx, PCM_OUT_SR_REG
407
           call [ctrl.ctrl_write16]
408
409
 
410
           call [ctrl.ctrl_read8]
411
412
 
413
           cmp eax, [civ_val]
414
           je .skip
415
416
 
417
           dec eax
418
           and eax, 0x1F
419
           mov [ctrl.lvi_reg], eax
420
421
 
422
           call [ctrl.ctrl_write8]
423
424
 
425
           mov ax, 0x11
426
           call [ctrl.ctrl_write8]
427
428
 
429
           add eax, 1
430
           and eax, 31
431
           mov ebx, dword [buff_list+eax*4]
432
433
 
434
           je @f
435
436
 
437
@@:
438
           ret
439
440
 
441
           mov edx, PCM_OUT_CR_REG
442
           mov ax, 0x11
443
           call [ctrl.ctrl_write8]
444
           ret
445
endp
446
447
 
448
proc create_primary_buff
449
450
 
451
           mov [ctrl.buffer], eax
452
453
 
454
           mov ecx, 0x10000/4
455
           xor eax, eax
456
           cld
457
           rep stosd
458
459
 
460
           call GetPgAddr
461
462
 
463
           mov ecx, 4
464
           mov edi, pcmout_bdl
465
@@:
466
           mov [edi], eax
467
           mov [edi+4], ebx
468
           mov [edi+32], eax
469
           mov [edi+4+32], ebx
470
           mov [edi+64], eax
471
           mov [edi+4+64], ebx
472
           mov [edi+96], eax
473
           mov [edi+4+96], ebx
474
           mov [edi+128], eax
475
           mov [edi+4+128], ebx
476
           mov [edi+160], eax
477
           mov [edi+4+160], ebx
478
           mov [edi+192], eax
479
           mov [edi+4+192], ebx
480
           mov [edi+224], eax
481
           mov [edi+4+224], ebx
482
483
 
484
           add edi, 8
485
           loop @B
486
487
 
488
           mov eax, [ctrl.buffer]
489
           mov ecx, 4
490
@@:
491
           mov [edi], eax
492
           mov [edi+16], eax
493
           mov [edi+32], eax
494
           mov [edi+48], eax
495
           mov [edi+64], eax
496
           mov [edi+80], eax
497
           mov [edi+96], eax
498
           mov [edi+112], eax
499
500
 
501
           add edi, 4
502
           loop @B
503
504
 
505
           mov ebx, eax
506
           call GetPgAddr     ;eax
507
           and ebx, 0xFFF
508
           add eax, ebx
509
510
 
511
           call [ctrl.ctrl_write32]
512
513
 
514
           mov [ctrl.lvi_reg], eax
515
           mov edx, PCM_OUT_LVI_REG
516
           call [ctrl.ctrl_write8]
517
518
 
519
           call [ctrl.ctrl_read32]
520
           and eax, not 0x000000C0
521
           mov edx, GLOB_CTRL
522
           call [ctrl.ctrl_write32]
523
524
 
525
 
526
endp
527
528
 
529
proc detect_controller
530
           locals
531
             last_bus dd ?
532
             bus      dd ?
533
             devfn    dd ?
534
           endl
535
536
 
537
           mov [bus], eax
538
           inc eax
539
           call PciApi
540
           cmp eax, -1
541
           je .err
542
543
 
544
545
 
546
           and [devfn], 0
547
.next_dev:
548
           stdcall PciRead32, [bus], [devfn], dword 0
549
           test eax, eax
550
           jz .next
551
           cmp eax, -1
552
           je .next
553
           mov edi, devices
554
@@:
555
           mov ebx, [edi]
556
           test ebx, ebx
557
           jz .next
558
559
 
560
           je .found
561
           add edi, 12
562
           jmp @B
563
564
 
565
           inc [devfn]
566
           cmp [devfn], 256
567
           jb  .next_dev
568
           mov eax, [bus]
569
           inc eax
570
           mov [bus], eax
571
           cmp eax, [last_bus]
572
           jna .next_bus
573
           xor eax, eax
574
           ret
575
.found:
576
           mov ebx, [bus]
577
           mov [ctrl.bus], ebx
578
579
 
580
           mov [ctrl.devfn], ecx
581
582
 
583
           and edx, 0xFFFF
584
           mov [ctrl.vendor], edx
585
           shr eax, 16
586
           mov [ctrl.dev_id], eax
587
588
 
589
           mov [ctrl.ctrl_ids], ebx
590
           mov [ctrl.vendor_ids], msg_SIS
591
592
 
593
           mov [ctrl.ctrl_setup], esi
594
           ret
595
.err:
596
           xor eax, eax
597
           ret
598
endp
599
600
 
601
proc init_controller
602
603
 
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
 
611
           and eax,0xFFFE
612
           mov [ctrl.codec_io_base], eax
613
614
 
615
           and eax, 0xFFC0
616
           mov [ctrl.ctrl_io_base], eax
617
618
 
619
           mov [ctrl.codec_mem_base], eax
620
621
 
622
           mov [ctrl.ctrl_mem_base], eax
623
624
 
625
           and eax, 0xFF
626
           mov [ctrl.int_line], eax
627
628
 
629
           and eax, 0xFF
630
           mov [ctrl.cfg_reg], eax
631
632
 
633
           xor eax, eax
634
           inc eax
635
           ret
636
endp
637
638
 
639
proc set_SIS
640
           mov [ctrl.codec_read16],  codec_io_r16    ;virtual
641
           mov [ctrl.codec_write16], codec_io_w16    ;virtual
642
643
 
644
           mov [ctrl.ctrl_read16],  ctrl_io_r16      ;virtual
645
           mov [ctrl.ctrl_read32],  ctrl_io_r32      ;virtual
646
647
 
648
           mov [ctrl.ctrl_write16], ctrl_io_w16      ;virtual
649
           mov [ctrl.ctrl_write32], ctrl_io_w32      ;virtual
650
           ret
651
endp
652
653
 
654
proc reset_controller
655
656
 
657
           mov edx, PCM_IN_CR_REG
658
           call [ctrl.ctrl_write8]
659
660
 
661
           call [ctrl.ctrl_write8]
662
663
 
664
           call [ctrl.ctrl_write8]
665
666
 
667
           mov edx, PCM_IN_CR_REG
668
           call [ctrl.ctrl_write8]
669
670
 
671
           call [ctrl.ctrl_write8]
672
673
 
674
           call [ctrl.ctrl_write8]
675
           ret
676
endp
677
678
 
679
proc init_codec
680
           locals
681
             counter dd ?
682
           endl
683
684
 
685
           call SysMsgBoardStr
686
687
 
688
           call [ctrl.ctrl_read32]
689
           call dword2str
690
           call SysMsgBoardStr
691
692
 
693
           call SysMsgBoardStr
694
695
 
696
           call [ctrl.ctrl_read32]
697
698
 
699
           call SysMsgBoardStr
700
701
 
702
           jnz .ready
703
704
 
705
           and eax, eax
706
           jz .err
707
708
 
709
           call [ctrl.codec_write16]
710
711
 
712
           mov edx, CODEC_REG_POWERDOWN
713
           call [ctrl.codec_write16]
714
715
 
716
.wait:
717
           mov edx, CODEC_REG_POWERDOWN
718
           call [ctrl.codec_read16]
719
           and eax, 0x0F
720
           cmp eax, 0x0F
721
           je .ready
722
723
 
724
           call StallExec
725
           sub [counter] , 1
726
           jnz .wait
727
.err:
728
           xor eax, eax        ; timeout error
729
           ret
730
.ready:
731
           call detect_codec
732
733
 
734
           inc eax
735
           ret
736
endp
737
738
 
739
proc reset_codec
740
           mov edx, GLOB_CTRL
741
           call [ctrl.ctrl_read32]
742
743
 
744
           jz .cold
745
746
 
747
           jnc .ok
748
.cold:
749
           call cold_reset
750
           jnc .ok
751
752
 
753
           mov esi, msgCFail
754
           call SysMsgBoardStr
755
     end if
756
           xor eax, eax     ; timeout error
757
           ret
758
.ok:
759
           xor eax, eax
760
           inc eax
761
           ret
762
endp
763
764
 
765
proc warm_reset
766
           locals
767
             counter dd ?
768
           endl
769
770
 
771
           mov edx, GLOB_CTRL
772
           call [ctrl.ctrl_write32]
773
774
 
775
           mov esi, msgWarm
776
           call SysMsgBoardStr
777
     end if
778
779
 
780
.wait:
781
           mov eax, 100000    ; wait 100 ms
782
           call StallExec
783
784
 
785
           call [ctrl.ctrl_read32]
786
           test eax, 4
787
           jz .ok
788
           sub [counter], 1
789
           jnz .wait
790
791
 
792
           mov esi, msgWRFail
793
           call SysMsgBoardStr
794
     end if
795
           stc
796
           ret
797
.ok:
798
           mov edx, CTRL_STAT
799
           call [ctrl.ctrl_read32]
800
           and eax, CTRL_ST_CREADY
801
           jz .fail
802
           clc
803
           ret
804
.fail:
805
           stc
806
           ret
807
endp
808
809
 
810
proc cold_reset
811
           locals
812
             counter dd ?
813
            endl
814
815
 
816
           call [ctrl.ctrl_read32]
817
           and eax, not 0x08
818
           or eax, 0x02
819
           mov edx, GLOB_CTRL
820
           call [ctrl.ctrl_write32]
821
822
 
823
           mov esi, msgCold
824
           call SysMsgBoardStr
825
     end if
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
842
     end if
843
.fail:
844
           stc
845
           ret
846
.ok:
847
           mov edx, CTRL_STAT
848
           call [ctrl.ctrl_read32]
849
           and eax, CTRL_ST_CREADY
850
           jz .fail
851
           clc
852
           ret
853
endp
854
855
 
856
proc play
857
           xor eax, eax
858
           mov [civ_val], eax
859
           mov edx, PCM_OUT_CIV_REG
860
           call [ctrl.ctrl_write8]
861
862
 
863
           mov [ctrl.lvi_reg], eax
864
           mov edx, PCM_OUT_LVI_REG
865
           call [ctrl.ctrl_write8]
866
867
 
868
           mov ax, 0x1D
869
           call [ctrl.ctrl_write8]
870
           ret
871
endp
872
873
 
874
proc stop
875
           mov edx, PCM_OUT_CR_REG
876
           mov ax, 0x0
877
           call [ctrl.ctrl_write8]
878
879
 
880
           mov edx, PCM_OUT_SR_REG
881
           call [ctrl.ctrl_write16]
882
           ret
883
endp
884
885
 
886
proc get_dev_info stdcall, p_info:dword
887
           virtual at esi
888
             CTRL_INFO CTRL_INFO
889
           end virtual
890
891
 
892
           mov eax, [ctrl.int_line]
893
           mov ebx, [ctrl.codec_io_base]
894
           mov ecx, [ctrl.ctrl_io_base]
895
           mov edx, [ctrl.codec_mem_base]
896
           mov edi, [ctrl.ctrl_mem_base]
897
898
 
899
           mov [CTRL_INFO.codec_io_base], ebx
900
           mov [CTRL_INFO.ctrl_io_base], ecx
901
           mov [CTRL_INFO.codec_mem_base], edx
902
           mov [CTRL_INFO.ctrl_mem_base], edi
903
904
 
905
           mov [CTRL_INFO.codec_id], eax
906
907
 
908
           call [ctrl.ctrl_read32]
909
           mov [CTRL_INFO.glob_cntrl], eax
910
911
 
912
           call [ctrl.ctrl_read32]
913
           mov [CTRL_INFO.glob_sta], eax
914
915
 
916
           mov [CTRL_INFO.pci_cmd], ebx
917
918
 
919
endp
920
921
 
922
proc set_callback stdcall, handler:dword
923
           mov eax, [handler]
924
           mov [ctrl.user_callback], eax
925
           ret
926
endp
927
928
 
929
proc codec_read stdcall, ac_reg:dword	   ; reg = edx, reval = eax
930
931
 
932
933
 
934
           shr ebx, 1
935
           bt [codec.shadow_flag], ebx
936
           jc .use_shadow
937
938
 
939
           mov ecx, eax
940
941
 
942
           call [ctrl.ctrl_read32]
943
           test eax, CTRL_ST_RCS
944
           jz .read_ok
945
946
 
947
           call [ctrl.ctrl_write32]
948
           xor eax,eax
949
           not eax  ;timeout
950
           ret
951
.read_ok:
952
           mov edx, [ac_reg]
953
           mov [codec.regs+edx], cx
954
           bts [codec.shadow_flag], ebx
955
           mov eax, ecx
956
           ret
957
.use_shadow:
958
           movzx eax, word [codec.regs+edx]
959
           ret
960
endp
961
962
 
963
proc codec_write stdcall, ac_reg:dword
964
           push eax
965
           call check_semafore
966
           and eax, eax
967
           jz .err
968
           pop eax
969
970
 
971
           mov edx, esi
972
           call [ctrl.codec_write16]
973
           mov [codec.regs+esi], ax
974
           shr esi, 1
975
           bts [codec.shadow_flag], esi
976
           ret
977
.err:
978
           pop eax
979
           ret
980
endp
981
982
 
983
 
984
proc codec_check_ready
985
986
 
987
           call [ctrl.ctrl_read32]
988
           and eax, CTRL_ST_CREADY
989
           jz .not_ready
990
991
 
992
           inc eax
993
           ret
994
995
 
996
.not_ready:
997
           xor eax, eax
998
           ret
999
endp
1000
1001
 
1002
 
1003
proc check_semafore
1004
           local counter:DWORD
1005
1006
 
1007
.l1:
1008
           mov edx, CTRL_CAS
1009
           call [ctrl.ctrl_read8]
1010
           and eax, CAS_FLAG
1011
           jz .ok
1012
1013
 
1014
           call StallExec
1015
           sub [counter], 1
1016
           jnz .l1
1017
           xor eax, eax
1018
           ret
1019
align 4
1020
.ok:
1021
           xor eax,eax
1022
           inc eax
1023
           ret
1024
endp
1025
1026
 
1027
proc StallExec
1028
           push ecx
1029
           push edx
1030
           push ebx
1031
           push eax
1032
1033
 
1034
           mul ecx
1035
           mov ebx, eax       ;low
1036
           mov ecx, edx       ;high
1037
           rdtsc
1038
           add ebx, eax
1039
           adc ecx, edx
1040
@@:
1041
           rdtsc
1042
           sub eax, ebx
1043
           sbb edx, ecx
1044
           js @B
1045
1046
 
1047
           pop ebx
1048
           pop edx
1049
           pop ecx
1050
           ret
1051
endp
1052
1053
 
1054
;          CONTROLLER IO functions
1055
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1056
1057
 
1058
proc codec_io_r16
1059
           add edx, [ctrl.codec_io_base]
1060
           in  ax, dx
1061
           ret
1062
endp
1063
1064
 
1065
proc codec_io_w16
1066
           add edx, [ctrl.codec_io_base]
1067
           out dx, ax
1068
           ret
1069
endp
1070
1071
 
1072
proc ctrl_io_r8
1073
           add edx, [ctrl.ctrl_io_base]
1074
           in  al, dx
1075
           ret
1076
endp
1077
1078
 
1079
proc ctrl_io_r16
1080
           add edx, [ctrl.ctrl_io_base]
1081
           in  ax, dx
1082
           ret
1083
endp
1084
1085
 
1086
proc ctrl_io_r32
1087
           add edx, [ctrl.ctrl_io_base]
1088
           in  eax, dx
1089
           ret
1090
endp
1091
1092
 
1093
proc ctrl_io_w8
1094
           add edx, [ctrl.ctrl_io_base]
1095
           out dx, al
1096
           ret
1097
endp
1098
1099
 
1100
proc ctrl_io_w16
1101
           add edx, [ctrl.ctrl_io_base]
1102
           out dx, ax
1103
           ret
1104
endp
1105
1106
 
1107
proc ctrl_io_w32
1108
           add edx, [ctrl.ctrl_io_base]
1109
           out dx, eax
1110
           ret
1111
endp
1112
1113
 
1114
dword2str:
1115
      mov  esi, hex_buff
1116
      mov ecx, -8
1117
@@:
1118
      rol eax, 4
1119
      mov ebx, eax
1120
      and ebx, 0x0F
1121
      mov bl, [ebx+hexletters]
1122
      mov [8+esi+ecx], bl
1123
      inc ecx
1124
      jnz @B
1125
      ret
1126
1127
 
1128
 
1129
1130
 
1131
devices dd (CTRL_SIS  shl 16)+VID_SIS,msg_AC, set_SIS
1132
        dd 0
1133
1134
 
1135
1136
 
1137
msg_SIS      db 'Silicon Integrated Systems',13,10, 0
1138
1139
 
1140
1141
 
1142
msgFail      db 'device not found',13,10,0
1143
msgPlay      db 'start play', 13,10,0
1144
msgStop      db 'stop play',  13,10,0
1145
msgNotify    db 'call notify',13,10,0
1146
msgIRQ       db 'AC97 IRQ', 13,10,0
1147
msgInitCtrl  db 'init controller',13,10,0
1148
msgInitCodec db 'init codec',13,10,0
1149
msgPrimBuff  db 'create primary buffer',13,10,0
1150
msgReg       db 'set service handler',13,10,0
1151
msgOk        db 'service installed',13,10,0
1152
msgCold      db 'cold resret',13,10,0
1153
msgWarm      db 'warm reset',13,10,0
1154
msgWRFail    db 'warm reset failed',13,10,0
1155
msgCRFail    db 'cold reset failed',13,10,0
1156
msgCFail     db 'codec not ready',13,10,0
1157
msgStatus    db 'global status   ',0
1158
msgControl   db 'global control  ',0
1159
1160
 
1161
hex_buff     db 8 dup(0),13,10,0
1162
1163
 
1164
 
1165
1166
 
1167
buff_list        rd 32
1168
1169
 
1170
ctrl AC_CNTRL
1171
1172
 
1173
civ_val  rd 1
1174