Subversion Repositories Kolibri OS

Rev

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

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