Subversion Repositories Kolibri OS

Rev

Rev 412 | 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
288
 
412 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, -16
412 serge 612
           mov [ctrl.ctrl_io_base], eax
613
381 serge 614
 
406 serge 615
           call SysMsgBoardStr
616
381 serge 617
 
412 serge 618
           call SysMsgBoardStr
406 serge 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
proc reset_controller
650
651
 
412 serge 652
           mov edx, PCM_IN_CR_REG
653
           call [ctrl.ctrl_write8]
654
381 serge 655
 
412 serge 656
           call [ctrl.ctrl_write8]
657
381 serge 658
 
412 serge 659
           call [ctrl.ctrl_write8]
660
381 serge 661
 
412 serge 662
           mov edx, PCM_IN_CR_REG
663
           call [ctrl.ctrl_write8]
664
381 serge 665
 
412 serge 666
           call [ctrl.ctrl_write8]
667
381 serge 668
 
412 serge 669
           call [ctrl.ctrl_write8]
670
           ret
671
endp
381 serge 672
673
 
674
proc init_codec
675
         locals
412 serge 676
           counter dd ?
677
         endl
678
381 serge 679
 
406 serge 680
           call SysMsgBoardStr
681
682
 
683
           call [ctrl.ctrl_read32]
684
           call dword2str
685
           call SysMsgBoardStr
686
687
 
688
           call SysMsgBoardStr
689
690
 
691
           call [ctrl.ctrl_read32]
692
693
 
694
           call SysMsgBoardStr
695
696
 
697
           jnz .ready
698
699
 
412 serge 700
           and eax, eax
701
           jz .err
702
381 serge 703
 
412 serge 704
           call [ctrl.codec_write16]
705
381 serge 706
 
412 serge 707
           mov edx, CODEC_REG_POWERDOWN
708
           call [ctrl.codec_write16]
709
381 serge 710
 
412 serge 711
.wait:
381 serge 712
           mov edx, CODEC_REG_POWERDOWN
412 serge 713
           call [ctrl.codec_read16]
714
           and eax, 0x0F
715
           cmp eax, 0x0F
716
           jz .ready
717
381 serge 718
 
412 serge 719
           call StallExec
720
           sub [counter] , 1
721
           jnz .wait
722
.err:
381 serge 723
           xor eax, eax        ; timeout error
412 serge 724
           ret
725
.ready:
381 serge 726
           call detect_codec
412 serge 727
381 serge 728
 
412 serge 729
           inc eax
730
           ret
731
endp
381 serge 732
733
 
734
proc reset_codec
735
           mov edx, GLOB_CTRL
406 serge 736
           call [ctrl.ctrl_read32]
737
381 serge 738
 
739
           jz .cold
740
741
 
742
           jnc .ok
743
.cold:
744
           call cold_reset
406 serge 745
           jnc .ok
746
381 serge 747
 
748
           mov esi, msgCFail
406 serge 749
           call SysMsgBoardStr
381 serge 750
     end if
751
           xor eax, eax     ; timeout error
406 serge 752
           ret
753
.ok:
381 serge 754
     if DEBUG
755
           mov esi, msgResetOk
756
           call SysMsgBoardStr
757
     end if
758
759
 
760
           inc eax
406 serge 761
           ret
762
endp
381 serge 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
796
 
797
	   ret
798
.ok:
799
	   mov edx, CTRL_STAT
800
	   call [ctrl.ctrl_read32]
801
	   and eax, CTRL_ST_CREADY
802
           jz .fail
803
           clc
804
	   ret
805
.fail:
806
           stc
807
	   ret
808
endp
809
810
 
811
proc cold_reset
812
	   locals
813
	     counter dd ?
814
	   endl
815
816
 
817
	   mov edx, GLOB_CTRL
818
	   call [ctrl.ctrl_write32]
819
820
 
821
	   mov esi, msgCold
822
           call SysMsgBoardStr
823
     end if
824
825
 
826
	   call StallExec
827
828
 
829
	   mov edx, GLOB_CTRL
830
	   call [ctrl.ctrl_write32]
831
832
 
833
.wait:
834
	   mov eax, 100000	   ; wait 100 ms
835
	   call StallExec
836
837
 
838
	   call [ctrl.ctrl_read32]
839
	   test eax, 4
840
	   jz .ok
841
	   sub [counter], 1
842
	   jnz .wait
843
844
 
845
	   mov esi, msgCRFail
846
           call SysMsgBoardStr
847
     end if
848
	   stc
849
	   ret
850
.ok:
851
	   mov edx, CTRL_STAT
852
	   call [ctrl.ctrl_read32]
853
	   and eax, CTRL_ST_CREADY
854
           jz .fail
855
           clc
856
	   ret
857
.fail:
858
           stc
859
	   ret
860
endp
861
862
 
863
play:
406 serge 864
           mov eax, 16
412 serge 865
           mov [ctrl.lvi_reg], eax
866
           mov edx, PCM_OUT_LVI_REG
867
           call [ctrl.ctrl_write8]
868
381 serge 869
 
412 serge 870
           mov ax, 0x1D
871
           call [ctrl.ctrl_write8]
872
           xor eax, eax
406 serge 873
           ret
412 serge 874
381 serge 875
 
876
stop:
406 serge 877
           mov edx, PCM_OUT_CR_REG
412 serge 878
           mov ax, 0x0
406 serge 879
           call [ctrl.ctrl_write8]
412 serge 880
381 serge 881
 
406 serge 882
           mov edx, PCM_OUT_SR_REG
883
           call [ctrl.ctrl_write16]
884
           xor eax, eax
885
	   ret
381 serge 886
887
 
888
proc get_dev_info stdcall, p_info:dword
889
	   virtual at esi
890
	     CTRL_INFO CTRL_INFO
891
	   end virtual
892
893
 
894
	   mov eax, [ctrl.int_line]
895
	   mov ebx, [ctrl.codec_io_base]
896
	   mov ecx, [ctrl.ctrl_io_base]
897
	   mov edx, [ctrl.codec_mem_base]
898
	   mov edi, [ctrl.ctrl_mem_base]
899
900
 
901
	   mov [CTRL_INFO.codec_io_base], ebx
902
	   mov [CTRL_INFO.ctrl_io_base], ecx
903
	   mov [CTRL_INFO.codec_mem_base], edx
904
	   mov [CTRL_INFO.ctrl_mem_base], edi
905
906
 
907
           mov [CTRL_INFO.codec_id], eax
908
909
 
910
           call [ctrl.ctrl_read32]
911
	   mov [CTRL_INFO.glob_cntrl], eax
912
913
 
914
           call [ctrl.ctrl_read32]
915
	   mov [CTRL_INFO.glob_sta], eax
916
917
 
918
	   mov [CTRL_INFO.pci_cmd], ebx
919
	   ret
920
endp
921
922
 
923
proc set_callback stdcall, handler:dword
924
	   mov eax, [handler]
925
	   mov [ctrl.user_callback], eax
926
	   ret
927
endp
928
929
 
930
proc codec_read stdcall, ac_reg:dword	   ; reg = edx, reval = eax
931
932
 
933
934
 
935
	   shr ebx, 1
936
	   bt [codec.shadow_flag], ebx
937
	   jc .use_shadow
938
939
 
940
	   mov ecx, eax
941
942
 
943
	   call [ctrl.ctrl_read32]
944
	   test eax, CTRL_ST_RCS
945
	   jz .read_ok
946
947
 
948
	   call [ctrl.ctrl_write32]
949
	   xor eax,eax
950
	   not eax		;timeout
951
	   ret
952
.read_ok:
953
	   mov edx, [ac_reg]
954
	   mov [codec.regs+edx], cx
955
	   bts [codec.shadow_flag], ebx
956
	   mov eax, ecx
957
	   ret
958
.use_shadow:
959
	   movzx eax, word [codec.regs+edx]
960
	   ret
961
endp
962
963
 
964
proc codec_write stdcall, ac_reg:dword
965
	   push eax
966
	   call check_semafore
967
	   and eax, eax
968
	   jz .err
969
	   pop eax
970
971
 
972
	   mov edx, esi
973
	   call [ctrl.codec_write16]
974
	   mov [codec.regs+esi], ax
975
	   shr esi, 1
976
	   bts [codec.shadow_flag], esi
977
	   ret
978
.err:
979
	   pop eax
980
	   ret
981
endp
982
983
 
984
proc codec_check_ready
985
986
 
412 serge 987
           call [ctrl.ctrl_read32]
988
           and eax, CTRL_ST_CREADY
989
           jz .not_ready
990
381 serge 991
 
412 serge 992
           inc eax
993
           ret
994
.not_ready:
381 serge 995
           xor eax, eax
412 serge 996
           ret
997
endp
381 serge 998
999
 
1000
proc check_semafore
1001
	   local counter:DWORD
1002
1003
 
1004
.l1:
1005
	   mov edx, CTRL_CAS
1006
	   call [ctrl.ctrl_read8]
1007
	   and eax, CAS_FLAG
1008
	   jz .ok
1009
1010
 
1011
	   call StallExec
1012
	   sub [counter], 1
1013
	   jnz .l1
1014
	   xor eax, eax
1015
	   ret
1016
align 4
1017
.ok:
1018
	   xor eax,eax
1019
	   inc eax
1020
	   ret
1021
endp
1022
1023
 
1024
proc StallExec
1025
	   push ecx
1026
	   push edx
1027
	   push ebx
1028
	   push eax
1029
1030
 
1031
	   mul ecx
1032
	   mov ebx, eax       ;low
1033
	   mov ecx, edx       ;high
1034
	   rdtsc
1035
	   add ebx, eax
1036
	   adc ecx,edx
1037
@@:
1038
	   rdtsc
1039
	   sub eax, ebx
1040
	   sbb edx, ecx
1041
           js @B
406 serge 1042
381 serge 1043
 
1044
	   pop ebx
1045
	   pop edx
1046
	   pop ecx
1047
	   ret
1048
endp
1049
1050
 
1051
;          CONTROLLER IO functions
1052
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1053
1054
 
1055
codec_io_r16:
412 serge 1056
           add edx, [ctrl.codec_io_base]
406 serge 1057
           in  ax, dx
1058
           ret
1059
381 serge 1060
 
1061
codec_io_w16:
412 serge 1062
           add edx, [ctrl.codec_io_base]
406 serge 1063
           out dx, ax
1064
           ret
1065
381 serge 1066
 
1067
ctrl_io_r8:
412 serge 1068
           add edx, [ctrl.ctrl_io_base]
406 serge 1069
           in  al, dx
1070
           ret
1071
381 serge 1072
 
1073
ctrl_io_r16:
412 serge 1074
          add edx, [ctrl.ctrl_io_base]
1075
          in  ax, dx
1076
          ret
1077
381 serge 1078
 
1079
ctrl_io_r32:
412 serge 1080
          add edx, [ctrl.ctrl_io_base]
1081
          in  eax, dx
1082
          ret
1083
381 serge 1084
 
1085
ctrl_io_w8:
412 serge 1086
          add edx, [ctrl.ctrl_io_base]
1087
          out dx, al
1088
          ret
1089
381 serge 1090
 
1091
ctrl_io_w16:
412 serge 1092
          add edx, [ctrl.ctrl_io_base]
1093
          out dx, ax
1094
          ret
1095
381 serge 1096
 
1097
ctrl_io_w32:
412 serge 1098
          add edx, [ctrl.ctrl_io_base]
1099
          out dx, eax
1100
          ret
1101
381 serge 1102
 
1103
 
1104
dword2str:
406 serge 1105
          mov  esi, hex_buff
412 serge 1106
          mov ecx, -8
1107
@@:
406 serge 1108
          rol eax, 4
412 serge 1109
          mov ebx, eax
1110
          and ebx, 0x0F
1111
          mov bl, [ebx+hexletters]
1112
          mov [8+esi+ecx], bl
1113
          inc ecx
1114
          jnz @B
1115
          ret
1116
381 serge 1117
 
406 serge 1118
hex_buff     db 8 dup(0),13,10,0
1119
381 serge 1120
 
1121
 
1122
1123
 
1124
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH
412 serge 1125
        dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH
1126
        dd 0    ;terminator
1127
381 serge 1128
 
412 serge 1129
381 serge 1130
 
412 serge 1131
msgVibra128  db 'Sound Blaster AudioPCI Vibra 128',13,10,0
1132
381 serge 1133
 
406 serge 1134
381 serge 1135
 
406 serge 1136
msgFail      db 'device not found',13,10,0
381 serge 1137
msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
1138
msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
1139
msgPlay      db 'start play', 13,10,0
1140
msgStop      db 'stop play',  13,10,0
1141
msgNotify    db 'call notify',13,10,0
1142
msgIRQ       db 'AC97 IRQ', 13,10,0
406 serge 1143
msgInitCtrl  db 'init controller',13,10,0
381 serge 1144
msgInitCodec db 'init codec',13,10,0
1145
msgPrimBuff  db 'create primary buffer',13,10,0
1146
msgReg       db 'set service handler',13,10,0
406 serge 1147
msgOk        db 'service installed',13,10,0
1148
msgCold      db 'cold reset',13,10,0
381 serge 1149
msgWarm      db 'warm reset',13,10,0
1150
msgWRFail    db 'warm reset failed',13,10,0
1151
msgCRFail    db 'cold reset failed',13,10,0
1152
msgCFail     db 'codec not ready',13,10,0
1153
msgResetOk   db 'reset complete',13,10,0
1154
msgStatus    db 'global status   ',0
406 serge 1155
msgControl   db 'global control  ',0
1156
msgPCIcmd    db 'PCI command     ',0
1157
msgIObase    db 'IO base         ',0
1158
msgIRQline   db 'IRQ line        ',0
412 serge 1159
381 serge 1160
 
1161
1162
 
1163
buff_list        rd 32
1164
1165
 
1166
ctrl AC_CNTRL
1167
1168
 
1169
civ_val  rd 1
1170