Subversion Repositories Kolibri OS

Rev

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

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