Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
444 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
 
417 serge 279
OS_BASE         equ 0x80000000
380 serge 280
SLOT_BASE       equ OS_BASE+0x0080000
351 diamond 281
 
282
public START
283
public service_proc
284
public version
285
 
286
section '.flat' code readable align 16
287
 
288
proc START stdcall, state:dword
289
 
290
           cmp [state], 1
291
           jne .stop
292
 
293
     if DEBUG
294
           mov esi, msgInit
295
           call SysMsgBoardStr
296
     end if
297
 
298
           call detect_controller
299
           test eax, eax
300
           jz .fail
301
 
302
     if DEBUG
303
           mov esi,[ctrl.vendor_ids]
304
           call SysMsgBoardStr
305
           mov esi, [ctrl.ctrl_ids]
306
           call SysMsgBoardStr
307
 
308
     end if
309
 
310
           call init_controller
311
           test eax, eax
312
           jz .fail
313
 
314
     if DEBUG
315
           mov esi, msgInitCodec
316
           call SysMsgBoardStr
317
     end if
318
 
319
           call init_codec
320
           test eax, eax
321
           jz .fail
322
 
323
     if DEBUG
324
           mov esi, [codec.ac_vendor_ids]
325
           call SysMsgBoardStr
326
 
327
           mov esi, [codec.chip_ids]
328
           call SysMsgBoardStr
329
     end if
330
 
331
           call reset_controller
332
           call setup_codec
333
 
334
           mov esi, msgPrimBuff
335
           call SysMsgBoardStr
336
 
337
           call create_primary_buff
338
 
339
;     if REMAP_IRQ
340
 
341
;           call get_LPC_bus
342
;           cmp eax, -1
343
;           jz .fail
344
 
345
;           mov [lpc_bus], 0  ;eax
346
;           call remap_irq
347
;     end if
348
 
349
           mov eax, VALID_IRQ
350
           mov ebx, [ctrl.int_line]
351
           mov esi, msgInvIRQ
352
           bt eax, ebx
353
           jnc .fail
354
           mov eax, ATTCH_IRQ
355
           mov esi, msgAttchIRQ
356
           bt eax, ebx
357
           jnc .fail
358
 
359
           stdcall AttachIntHandler, ebx, ac97_irq
419 serge 360
.reg:
351 diamond 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]
422
           stdcall get_master_vol, ebx
423
           ret
378 serge 424
;@@:
425
;           cmp eax, DEV_GET_INFO
426
;           jne @F
427
;           mov ebx, [edi+output]
428
;           stdcall get_dev_info, ebx
429
;           ret
351 diamond 430
@@:
431
.fail:
378 serge 432
           or eax, -1
351 diamond 433
           ret
434
endp
435
 
436
restore   handle
437
restore   io_code
438
restore   input
439
restore   inp_size
440
restore   output
441
restore   out_size
442
 
443
 
444
align 4
445
proc remap_irq                         ;for Intel chipsets ONLY !!!
446
           mov eax, VALID_IRQ
447
           bt eax, IRQ_LINE
448
           jnc .exit
449
 
450
           mov edx, 0x4D0
451
           in ax,dx
452
           bts ax, IRQ_LINE
453
           out dx, aX
454
 
455
           stdcall PciWrite8, dword 0, dword 0xF8, dword 0x61, dword IRQ_LINE
456
           mov [ctrl.int_line], IRQ_LINE
457
 
458
.exit:
459
	   ret
460
endp
461
 
462
align 4
463
proc ac97_irq
464
 
465
;     if DEBUG
466
;           mov esi, msgIRQ
467
;           call SysMsgBoardStr
468
;     end if
469
 
470
           mov edx, PCM_OUT_CR_REG
471
           mov al, 0x10;               0x10
472
           call [ctrl.ctrl_write8]
473
 
474
           mov ax, 0x1c
475
           mov edx, PCM_OUT_SR_REG
476
           call [ctrl.ctrl_write16]
477
 
478
           mov edx, PCM_OUT_CIV_REG
479
           call [ctrl.ctrl_read8]
480
 
481
           and eax, 0x1F
482
           cmp eax, [civ_val]
483
           je .skip
484
 
485
           mov [civ_val], eax
486
           dec eax
487
           and eax, 0x1F
488
           mov [ctrl.lvi_reg], eax
489
 
490
           mov edx, PCM_OUT_LVI_REG
491
           call [ctrl.ctrl_write8]
492
 
493
           mov edx, PCM_OUT_CR_REG
494
           mov ax, 0x11              ;0x1D
495
           call [ctrl.ctrl_write8]
496
 
497
           mov eax, [civ_val]
498
           add eax, 1
499
           and eax, 31
500
           mov ebx, dword [buff_list+eax*4]
501
 
502
           cmp [ctrl.user_callback], 0
503
           je @f
504
 
505
           stdcall [ctrl.user_callback], ebx
506
@@:
507
           ret
508
 
509
.skip:
510
           mov edx, PCM_OUT_CR_REG
511
           mov ax, 0x11               ;0x1D
512
           call [ctrl.ctrl_write8]
513
           ret
514
endp
515
 
516
align 4
517
proc create_primary_buff
518
 
519
           stdcall KernelAlloc, 0x10000
520
           mov [ctrl.buffer], eax
521
 
522
           mov edi, eax
523
           mov ecx, 0x10000/4
524
           xor eax, eax
525
           cld
526
           rep stosd
527
 
528
           mov eax, [ctrl.buffer]
529
           call GetPgAddr
530
 
531
           mov ebx, 0xC0002000
532
           mov ecx, 4
533
           mov edi, pcmout_bdl
534
@@:
535
           mov [edi], eax
536
           mov [edi+4], ebx
537
 
538
           mov [edi+32], eax
539
           mov [edi+4+32], ebx
540
 
541
           mov [edi+64], eax
542
           mov [edi+4+64], ebx
543
 
544
           mov [edi+96], eax
545
           mov [edi+4+96], ebx
546
 
547
           mov [edi+128], eax
548
           mov [edi+4+128], ebx
549
 
550
           mov [edi+160], eax
551
           mov [edi+4+160], ebx
552
 
553
           mov [edi+192], eax
554
           mov [edi+4+192], ebx
555
 
556
           mov [edi+224], eax
557
           mov [edi+4+224], ebx
558
 
559
           add eax, 0x4000
560
           add edi, 8
561
           loop @B
562
 
563
           mov edi, buff_list
564
           mov eax, [ctrl.buffer]
565
           mov ecx, 4
566
@@:
567
           mov [edi], eax
568
           mov [edi+16], eax
569
           mov [edi+32], eax
570
           mov [edi+48], eax
571
           mov [edi+64], eax
572
           mov [edi+80], eax
573
           mov [edi+96], eax
574
           mov [edi+112], eax
575
 
576
           add eax, 0x4000
577
           add edi, 4
578
           loop @B
579
 
580
           mov eax, pcmout_bdl
581
           mov ebx, eax
582
           call GetPgAddr     ;eax
583
           and ebx, 0xFFF
584
           add eax, ebx
585
 
586
           mov edx, PCM_OUT_BDL
587
           call [ctrl.ctrl_write32]
588
 
589
           mov eax, 16
590
           mov [ctrl.lvi_reg], eax
591
           mov edx, PCM_OUT_LVI_REG
592
           call [ctrl.ctrl_write8]
593
           ret
594
endp
595
 
596
align 4
597
proc detect_controller
598
	   locals
599
	     last_bus dd ?
600
	     bus      dd ?
601
	     devfn    dd ?
602
	   endl
603
 
604
           xor eax, eax
605
           mov [bus], eax
606
           inc eax
607
           call PciApi
608
           cmp eax, -1
609
           je .err
610
 
611
           mov [last_bus], eax
612
 
613
.next_bus:
614
           and [devfn], 0
615
.next_dev:
616
           stdcall PciRead32, [bus], [devfn], dword 0
617
           test eax, eax
618
           jz .next
619
           cmp eax, -1
620
           je .next
621
 
622
           mov edi, devices
623
@@:
624
           mov ebx, [edi]
625
           test ebx, ebx
626
           jz .next
627
 
628
           cmp eax, ebx
629
           je .found
630
           add edi, 12
631
           jmp @B
632
 
633
.next:
634
           inc [devfn]
635
           cmp [devfn], 256
636
           jb .next_dev
637
           mov eax, [bus]
638
           inc eax
639
           mov [bus], eax
640
           cmp eax, [last_bus]
641
           jna .next_bus
642
           xor eax, eax
643
           ret
644
.found:
645
           mov ebx, [bus]
646
           mov [ctrl.bus], ebx
647
 
648
           mov ecx, [devfn]
649
           mov [ctrl.devfn], ecx
650
 
651
           mov edx, eax
652
           and edx, 0xFFFF
653
           mov [ctrl.vendor], edx
654
           shr eax, 16
655
           mov [ctrl.dev_id], eax
656
 
657
           mov ebx, [edi+4]
658
           mov [ctrl.ctrl_ids], ebx
659
           mov esi, [edi+8]
660
           mov [ctrl.ctrl_setup], esi
661
 
662
           cmp ebx, VID_INTEL
663
           jne @F
664
           mov [ctrl.vendor_ids], msg_Intel
665
           ret
666
@@:
667
           cmp ebx, VID_NVIDIA
668
           jne @F
669
           mov [ctrl.vendor_ids], msg_NVidia
670
@@:
671
           mov [ctrl.vendor_ids], 0     ;something  wrong ?
672
           ret
673
.err:
674
           xor eax, eax
675
           ret
676
endp
677
 
678
align 4
679
proc get_LPC_bus                ;for Intel chipsets ONLY !!!
680
           locals
681
             last_bus dd ?
682
             bus      dd ?
683
           endl
684
 
685
           xor eax, eax
686
           mov [bus], eax
687
           inc eax
688
           call [PciApi]
689
           cmp eax, -1
690
           je .err
691
 
692
           mov [last_bus], eax
693
.next_bus:
694
           stdcall PciRead32, [bus], dword 0xF8, dword 0
695
           test eax, eax
696
           jz .next
697
           cmp eax, -1
698
           je .next
699
 
700
           cmp eax, 0x24D08086
701
           je .found
702
.next:
703
           mov eax, [bus]
704
           inc eax
705
           cmp eax, [last_bus]
706
           mov [bus], eax
707
           jna .next_bus
708
.err:
709
           xor eax, eax
710
           dec eax
711
           ret
712
.found:
713
           mov eax, [bus]
714
           ret
715
endp
716
 
717
align 4
718
proc init_controller
719
 
720
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
721
           mov ebx, eax
722
           and eax, 0xFFFF
723
           mov [ctrl.pci_cmd], eax
724
           shr ebx, 16
725
           mov [ctrl.pci_stat], ebx
726
 
727
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
728
           and eax,0xFFFE
729
           mov [ctrl.codec_io_base], eax
730
 
731
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
732
           and eax, 0xFFC0
733
           mov [ctrl.ctrl_io_base], eax
734
 
735
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
736
           mov [ctrl.codec_mem_base], eax
737
 
738
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
739
           mov [ctrl.ctrl_mem_base], eax
740
 
741
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
742
           and eax, 0xFF
743
           mov [ctrl.int_line], eax
744
 
745
           stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41
746
           and eax, 0xFF
747
           mov [ctrl.cfg_reg], eax
748
 
749
           call [ctrl.ctrl_setup]
750
           xor eax, eax
751
           inc eax
752
           ret
753
endp
754
 
755
align 4
756
proc set_ICH
757
           mov [ctrl.codec_read16],  codec_io_r16    ;virtual
758
           mov [ctrl.codec_write16], codec_io_w16    ;virtual
759
 
760
           mov [ctrl.ctrl_read8 ],  ctrl_io_r8      ;virtual
761
           mov [ctrl.ctrl_read16],  ctrl_io_r16      ;virtual
762
           mov [ctrl.ctrl_read32],  ctrl_io_r32      ;virtual
763
 
764
           mov [ctrl.ctrl_write8 ], ctrl_io_w8      ;virtual
765
           mov [ctrl.ctrl_write16], ctrl_io_w16      ;virtual
766
           mov [ctrl.ctrl_write32], ctrl_io_w32      ;virtual
767
           ret
768
endp
769
 
378 serge 770
PG_SW            equ 0x003
771
PG_NOCACHE       equ 0x018
351 diamond 772
 
773
align 4
774
proc set_ICH4
775
           stdcall AllocKernelSpace, dword 0x2000
776
           mov edi, eax
777
           stdcall MapPage, edi,[ctrl.codec_mem_base],PG_SW+PG_NOCACHE
778
           mov [ctrl.codec_mem_base], edi
779
           add edi, 0x1000
780
           stdcall MapPage, edi, [ctrl.ctrl_mem_base],PG_SW+PG_NOCACHE
781
           mov [ctrl.ctrl_mem_base], edi
782
 
783
           mov [ctrl.codec_read16],  codec_mem_r16    ;virtual
784
           mov [ctrl.codec_write16], codec_mem_w16    ;virtual
785
 
786
           mov [ctrl.ctrl_read8 ],  ctrl_mem_r8       ;virtual
787
           mov [ctrl.ctrl_read16],  ctrl_mem_r16      ;virtual
788
           mov [ctrl.ctrl_read32],  ctrl_mem_r32      ;virtual
789
 
790
           mov [ctrl.ctrl_write8 ], ctrl_mem_w8       ;virtual
791
           mov [ctrl.ctrl_write16], ctrl_mem_w16      ;virtual
792
           mov [ctrl.ctrl_write32], ctrl_mem_w32      ;virtual
793
           ret
794
endp
795
 
796
align 4
797
proc reset_controller
798
 
799
           xor eax, eax
800
           mov edx, PCM_IN_CR_REG
801
           call [ctrl.ctrl_write8]
802
 
803
           mov edx, PCM_OUT_CR_REG
804
           call [ctrl.ctrl_write8]
805
 
806
           mov edx, MC_IN_CR_REG
807
           call [ctrl.ctrl_write8]
808
 
809
           mov eax, RR
810
           mov edx, PCM_IN_CR_REG
811
           call [ctrl.ctrl_write8]
812
 
813
           mov edx, PCM_OUT_CR_REG
814
           call [ctrl.ctrl_write8]
815
 
816
           mov edx, MC_IN_CR_REG
817
           call [ctrl.ctrl_write8]
818
           ret
819
endp
820
 
821
align 4
822
proc init_codec
823
           locals
824
             counter dd ?
825
           endl
826
 
827
           mov esi, msgControl
828
           call SysMsgBoardStr
829
 
830
           mov edx, GLOB_CTRL
831
           call [ctrl.ctrl_read32]
832
           call dword2str
833
           call SysMsgBoardStr
834
 
835
           mov esi, msgStatus
836
           call SysMsgBoardStr
837
 
838
           mov edx, CTRL_STAT
839
           call [ctrl.ctrl_read32]
840
 
841
           call dword2str
842
           call SysMsgBoardStr
843
 
844
           test eax, CTRL_ST_CREADY
845
           jnz .ready
846
 
847
           call reset_codec
848
           and eax, eax
849
           jz .err
850
 
851
           xor edx, edx     ;ac_reg_0
852
           call [ctrl.codec_write16]
853
 
854
           xor eax, eax
855
           mov edx, CODEC_REG_POWERDOWN
856
           call [ctrl.codec_write16]
857
 
858
           mov [counter], 200     ; total 200*5 ms = 1s
859
.wait:
860
           mov edx, CODEC_REG_POWERDOWN
861
           call [ctrl.codec_read16]
862
           and eax, 0x0F
863
           cmp eax, 0x0F
864
           jz .ready
865
 
866
           mov eax, 5000   ; wait 5 ms
867
           call StallExec
868
           sub [counter] , 1
869
           jnz .wait
870
.err:
871
           xor eax, eax        ; timeout error
872
           ret
873
.ready:
874
           call detect_codec
875
 
876
           xor eax, eax
877
           inc eax
878
           ret
879
endp
880
 
881
align 4
882
proc reset_codec
883
           mov edx, GLOB_CTRL
884
           call [ctrl.ctrl_read32]
885
 
886
           test eax, 0x02
887
           jz .cold
888
 
889
           call warm_reset
890
           jnc .ok
891
.cold:
892
           call cold_reset
893
           jnc .ok
894
 
895
     if DEBUG
896
           mov esi, msgCFail
897
           call SysMsgBoardStr
898
           end if
899
           xor eax, eax     ; timeout error
900
           ret
901
.ok:
902
     if DEBUG
903
           mov esi, msgResetOk
904
           call SysMsgBoardStr
905
     end if
906
 
907
           xor eax, eax
908
           inc eax
909
           ret
910
endp
911
 
912
align 4
913
proc warm_reset
914
           locals
915
             counter dd ?
916
           endl
917
 
918
           mov eax, 0x06
919
           mov edx, GLOB_CTRL
920
           call [ctrl.ctrl_write32]
921
 
922
     if DEBUG
923
           mov esi, msgWarm
924
           call SysMsgBoardStr
925
     end if
926
 
927
           mov [counter], 10    ; total 10*100 ms = 1s
928
.wait:
929
           mov eax, 100000    ; wait 100 ms
930
           call StallExec
931
 
932
           mov edx, GLOB_CTRL
933
           call [ctrl.ctrl_read32]
934
           test eax, 4
935
           jz .ok
936
           sub [counter], 1
937
           jnz .wait
938
 
939
     if DEBUG
940
           mov esi, msgWRFail
941
           call SysMsgBoardStr
942
     end if
943
 
944
           stc
945
           ret
946
.ok:
947
           mov edx, CTRL_STAT
948
           call [ctrl.ctrl_read32]
949
           and eax, CTRL_ST_CREADY
950
           jz .fail
951
           clc
952
           ret
953
.fail:
954
           stc
955
	   ret
956
endp
957
 
958
align 4
959
proc cold_reset
960
           locals
961
             counter dd ?
962
           endl
963
 
964
           xor eax, eax
965
           mov edx, GLOB_CTRL
966
           call [ctrl.ctrl_write32]
967
 
968
     if DEBUG
969
           mov esi, msgCold
970
           call SysMsgBoardStr
971
     end if
972
 
973
           mov eax, 1000000    ; wait 1 s
974
           call StallExec
975
 
976
           mov eax, 2
977
           mov edx, GLOB_CTRL
978
           call [ctrl.ctrl_write32]
979
 
980
           mov [counter], 10    ; total 10*100 ms = 1s
981
.wait:
982
           mov eax, 100000    ; wait 100 ms
983
           call StallExec
984
 
985
           mov edx, GLOB_CTRL
986
           call [ctrl.ctrl_read32]
987
           test eax, 4
988
           jz .ok
989
           sub [counter], 1
990
           jnz .wait
991
 
992
     if DEBUG
993
           mov esi, msgCRFail
994
           call SysMsgBoardStr
995
     end if
996
           stc
997
           ret
998
.ok:
999
           mov edx, CTRL_STAT
1000
           call [ctrl.ctrl_read32]
1001
           and eax, CTRL_ST_CREADY
1002
           jz .fail
1003
           clc
1004
           ret
1005
.fail:
1006
           stc
1007
           ret
1008
endp
1009
 
1010
align 4
378 serge 1011
play:
351 diamond 1012
           mov eax, 16
1013
           mov [ctrl.lvi_reg], eax
1014
           mov edx, PCM_OUT_LVI_REG
1015
           call [ctrl.ctrl_write8]
1016
 
1017
           mov edx, PCM_OUT_CR_REG
1018
           mov ax, 0x1D
1019
           call [ctrl.ctrl_write8]
378 serge 1020
           xor eax, eax
351 diamond 1021
           ret
1022
 
1023
align 4
378 serge 1024
stop:
351 diamond 1025
           mov edx, PCM_OUT_CR_REG
1026
           mov ax, 0x0
1027
           call [ctrl.ctrl_write8]
1028
 
1029
           mov ax, 0x1c
1030
           mov edx, PCM_OUT_SR_REG
1031
           call [ctrl.ctrl_write16]
378 serge 1032
           xor eax, eax
351 diamond 1033
           ret
1034
 
1035
align 4
1036
proc get_dev_info stdcall, p_info:dword
1037
           virtual at esi
1038
             CTRL_INFO CTRL_INFO
1039
           end virtual
1040
 
1041
           mov esi, [p_info]
1042
           mov eax, [ctrl.int_line]
1043
           mov ebx, [ctrl.codec_io_base]
1044
           mov ecx, [ctrl.ctrl_io_base]
1045
           mov edx, [ctrl.codec_mem_base]
1046
           mov edi, [ctrl.ctrl_mem_base]
1047
 
1048
           mov [CTRL_INFO.irq], eax
1049
           mov [CTRL_INFO.codec_io_base], ebx
1050
           mov [CTRL_INFO.ctrl_io_base], ecx
1051
           mov [CTRL_INFO.codec_mem_base], edx
1052
           mov [CTRL_INFO.ctrl_mem_base], edi
1053
 
1054
           mov eax, [codec.chip_id]
1055
           mov [CTRL_INFO.codec_id], eax
1056
 
1057
           mov edx, GLOB_CTRL
1058
           call [ctrl.ctrl_read32]
1059
           mov [CTRL_INFO.glob_cntrl], eax
1060
 
1061
           mov edx, CTRL_STAT
1062
           call [ctrl.ctrl_read32]
1063
           mov [CTRL_INFO.glob_sta], eax
1064
 
1065
           mov ebx, [ctrl.pci_cmd]
1066
           mov [CTRL_INFO.pci_cmd], ebx
1067
           ret
1068
endp
1069
 
1070
align 4
1071
proc set_callback stdcall, handler:dword
1072
           mov eax, [handler]
1073
           mov [ctrl.user_callback], eax
1074
           ret
1075
endp
1076
 
1077
align 4
1078
proc codec_read stdcall, ac_reg:dword	   ; reg = edx, reval = eax
1079
 
1080
           mov edx, [ac_reg]
1081
 
1082
           mov ebx, edx
1083
           shr ebx, 1
1084
           bt [codec.shadow_flag], ebx
1085
           jc .use_shadow
1086
 
1087
           call [ctrl.codec_read16]  ;change edx !!!
1088
           mov ecx, eax
1089
 
1090
           mov edx, CTRL_STAT
1091
           call [ctrl.ctrl_read32]
1092
           test eax, CTRL_ST_RCS
1093
           jz .read_ok
1094
 
1095
           mov edx, CTRL_STAT
1096
           call [ctrl.ctrl_write32]
1097
           xor eax,eax
1098
           not eax  ;timeout
1099
           ret
1100
.read_ok:
1101
           mov edx, [ac_reg]
1102
           mov [codec.regs+edx], cx
1103
           bts [codec.shadow_flag], ebx
1104
           mov eax, ecx
1105
           ret
1106
.use_shadow:
1107
           movzx eax, word [codec.regs+edx]
1108
           ret
1109
endp
1110
 
1111
align 4
1112
proc codec_write stdcall, ac_reg:dword
1113
           push eax
1114
           call check_semafore
1115
           and eax, eax
1116
           jz .err
1117
           pop eax
1118
 
1119
           mov esi, [ac_reg]
1120
           mov edx, esi
1121
           call [ctrl.codec_write16]
1122
           mov [codec.regs+esi], ax
1123
           shr esi, 1
1124
           bts [codec.shadow_flag], esi
1125
           ret
1126
.err:
1127
           pop eax
1128
           ret
1129
endp
1130
 
1131
align 4
1132
proc codec_check_ready
1133
 
1134
           mov edx, CTRL_ST
1135
           call [ctrl.ctrl_read32]
1136
           and eax, CTRL_ST_CREADY
1137
           jz .not_ready
1138
 
1139
           xor eax, wax
1140
           inc eax
1141
           ret
1142
.not_ready:
1143
           xor eax, eax
1144
           ret
1145
endp
1146
 
1147
align 4
1148
proc check_semafore
1149
           local counter:DWORD
1150
 
1151
           mov [counter], 100
1152
.l1:
1153
           mov edx, CTRL_CAS
1154
           call [ctrl.ctrl_read8]
1155
           and eax, CAS_FLAG
1156
           jz .ok
1157
 
1158
           mov eax, 1
1159
           call StallExec
1160
           sub [counter], 1
1161
           jnz .l1
1162
           xor eax, eax
1163
           ret
1164
align 4
1165
.ok:
1166
           xor eax,eax
1167
           inc eax
1168
           ret
1169
endp
1170
 
1171
align 4
1172
proc StallExec
1173
           push ecx
1174
           push edx
1175
           push ebx
1176
           push eax
1177
 
1178
           mov ecx, CPU_FREQ
1179
           mul ecx
1180
           mov ebx, eax       ;low
1181
           mov ecx, edx       ;high
1182
           rdtsc
1183
           add ebx, eax
1184
           adc ecx,edx
1185
@@:
1186
           rdtsc
1187
           sub eax, ebx
1188
           sbb edx, ecx
1189
           js @B
1190
 
1191
           pop eax
1192
           pop ebx
1193
           pop edx
1194
           pop ecx
1195
           ret
1196
endp
1197
 
1198
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1199
;          CONTROLLER IO functions
1200
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1201
 
1202
align 4
1203
proc codec_io_r16
1204
           add edx, [ctrl.codec_io_base]
1205
           in  ax, dx
1206
           ret
1207
endp
1208
 
1209
align 4
1210
proc codec_io_w16
1211
           add edx, [ctrl.codec_io_base]
1212
           out dx, ax
1213
           ret
1214
endp
1215
 
1216
align 4
1217
proc ctrl_io_r8
1218
           add edx, [ctrl.ctrl_io_base]
1219
           in  al, dx
1220
           ret
1221
endp
1222
 
1223
align 4
1224
proc ctrl_io_r16
1225
           add edx, [ctrl.ctrl_io_base]
1226
           in  ax, dx
1227
           ret
1228
endp
1229
 
1230
align 4
1231
proc ctrl_io_r32
1232
           add edx, [ctrl.ctrl_io_base]
1233
           in  eax, dx
1234
           ret
1235
endp
1236
 
1237
align 4
1238
proc ctrl_io_w8
1239
           add edx, [ctrl.ctrl_io_base]
1240
           out dx, al
1241
           ret
1242
endp
1243
 
1244
align 4
1245
proc ctrl_io_w16
1246
           add edx, [ctrl.ctrl_io_base]
1247
           out dx, ax
1248
           ret
1249
endp
1250
 
1251
align 4
1252
proc ctrl_io_w32
1253
           add edx, [ctrl.ctrl_io_base]
1254
           out dx, eax
1255
           ret
1256
endp
1257
 
1258
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1259
;         MEMORY MAPPED IO    (os depended)
1260
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1261
 
1262
align 4
1263
proc codec_mem_r16
1264
           add edx, [ctrl.codec_mem_base]
1265
           mov ax, word [edx]
1266
           ret
1267
endp
1268
 
1269
align 4
1270
proc codec_mem_w16
1271
           add edx, [ctrl.codec_mem_base]
1272
           mov word [edx], ax
1273
           ret
1274
endp
1275
 
1276
align 4
1277
proc ctrl_mem_r8
1278
           add edx, [ctrl.ctrl_mem_base]
1279
           mov al, [edx]
1280
           ret
1281
endp
1282
 
1283
align 4
1284
proc ctrl_mem_r16
1285
           add edx, [ctrl.ctrl_mem_base]
1286
           mov ax, [edx]
1287
           ret
1288
endp
1289
 
1290
align 4
1291
proc ctrl_mem_r32
1292
           add edx, [ctrl.ctrl_mem_base]
1293
           mov eax, [edx]
1294
           ret
1295
endp
1296
 
1297
align 4
1298
proc ctrl_mem_w8
1299
           add edx, [ctrl.ctrl_mem_base]
1300
           mov [edx], al
1301
           ret
1302
endp
1303
 
1304
align 4
1305
proc ctrl_mem_w16
1306
           add edx, [ctrl.ctrl_mem_base]
1307
           mov [edx], ax
1308
           ret
1309
endp
1310
 
1311
align 4
1312
proc ctrl_mem_w32
1313
           add edx, [ctrl.ctrl_mem_base]
1314
           mov [edx], eax
1315
           ret
1316
endp
1317
 
1318
align 4
1319
dword2str:
1320
      mov  esi, hex_buff
1321
      mov ecx, -8
1322
@@:
1323
      rol eax, 4
1324
      mov ebx, eax
1325
      and ebx, 0x0F
1326
      mov bl, [ebx+hexletters]
1327
      mov [8+esi+ecx], bl
1328
      inc ecx
1329
      jnz @B
1330
      ret
1331
 
1332
hexletters   db '0123456789ABCDEF'
1333
hex_buff     db 8 dup(0),13,10,0
1334
 
1335
 
1336
include "codec.inc"
1337
 
1338
align 4
1339
devices dd (CTRL_ICH  shl 16)+VID_INTEL,msg_ICH, set_ICH
378 serge 1340
        dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH
1341
        dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH
1342
        dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH
351 diamond 1343
        dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4
1344
        dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4
1345
        dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4
1346
        dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4
1347
 
1348
        dd (CTRL_NFORCE  shl 16)+VID_NVIDIA,msg_NForce, set_ICH
1349
        dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH
1350
        dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH
1351
        dd (CTRL_MCP04   shl 16)+VID_NVIDIA,msg_MCP04,set_ICH
1352
        dd (CTRL_CK804   shl 16)+VID_NVIDIA,msg_CK804,set_ICH
1353
        dd (CTRL_CK8     shl 16)+VID_NVIDIA,msg_CK8,set_ICH
1354
        dd (CTRL_CK8S    shl 16)+VID_NVIDIA,msg_CK8S,set_ICH
1355
        dd (CTRL_MCP51   shl 16)+VID_NVIDIA,msg_MCP51,set_ICH
1356
 
1357
        dd 0    ;terminator
1358
 
378 serge 1359
version      dd 0x00040004
351 diamond 1360
 
1361
msg_ICH      db 'Intel ICH',  13,10, 0
1362
msg_ICH0     db 'Intel ICH0', 13,10, 0
1363
msg_ICH2     db 'Intel ICH2', 13,10, 0
1364
msg_ICH3     db 'Intel ICH3', 13,10, 0
1365
msg_ICH4     db 'Intel ICH4', 13,10, 0
1366
msg_ICH5     db 'Intel ICH5', 13,10, 0
1367
msg_ICH6     db 'Intel ICH6', 13,10, 0
1368
msg_ICH7     db 'Intel ICH7', 13,10, 0
1369
msg_Intel    db 'Intel Corp. ', 0
1370
 
1371
msg_NForce   db 'NForce',      13,10, 0
1372
msg_NForce2  db 'NForce 2',    13,10, 0
1373
msg_NForce3  db 'NForce 3',    13,10, 0
1374
msg_MCP04    db 'NForce MCP04',13,10, 0
1375
msg_CK804    db 'NForce CK804',13,10, 0
1376
msg_CK8      db 'NForce CK8',  13,10, 0
1377
msg_CK8S     db 'NForce CK8S', 13,10, 0
1378
msg_MCP51    db 'NForce MCP51',13,10, 0
1379
 
1380
msg_NVidia   db 'NVidia', 0
1381
 
1382
szKernel	    db 'KERNEL', 0
1383
sz_sound_srv	    db 'SOUND',0
1384
 
1385
msgInit      db 'detect hardware...',13,10,0
1386
msgFail      db 'device not found',13,10,0
1387
msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
1388
msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
1389
msgPlay      db 'start play', 13,10,0
1390
msgStop      db 'stop play',  13,10,0
1391
msgNotify    db 'call notify',13,10,0
1392
msgIRQ       db 'AC97 IRQ', 13,10,0
1393
msgInitCtrl  db 'init controller',13,10,0
1394
msgInitCodec db 'init codec',13,10,0
1395
msgPrimBuff  db 'create primary buffer',13,10,0
1396
msgReg       db 'set service handler',13,10,0
1397
msgOk        db 'service installed',13,10,0
1398
msgCold      db 'cold reset',13,10,0
1399
msgWarm      db 'warm reset',13,10,0
1400
msgWRFail    db 'warm reset failed',13,10,0
1401
msgCRFail    db 'cold reset failed',13,10,0
1402
msgCFail     db 'codec not ready',13,10,0
1403
msgResetOk   db 'reset complete',13,10,0
1404
msgStatus    db 'global status   ',0
1405
msgControl   db 'global control  ',0
1406
 
1407
section '.data' data readable writable align 16
1408
 
1409
pcmout_bdl       rq 32
1410
buff_list        rd 32
1411
 
1412
codec CODEC
1413
ctrl AC_CNTRL
1414
 
1415
lpc_bus  rd 1
1416
civ_val  rd 1