Subversion Repositories Kolibri OS

Rev

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

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