Subversion Repositories Kolibri OS

Rev

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