Subversion Repositories Kolibri OS

Rev

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

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