Subversion Repositories Kolibri OS

Rev

Rev 864 | Details | Compare with Previous | Last modification | View Log | RSS feed

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