Subversion Repositories Kolibri OS

Rev

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

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