Subversion Repositories Kolibri OS

Rev

Rev 431 | 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
 
465 serge 260
OS_BASE         equ 0x80000000
406 serge 261
SLOT_BASE       equ OS_BASE+0x0080000
465 serge 262
new_app_base    equ 0
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]
394
           stdcall get_master_vol, ebx
406 serge 395
           ret
396
;@@:
397
;           cmp eax, DEV_GET_INFO
398
;           jne @F
399
;           mov ebx, [edi+output]
400
;           stdcall get_dev_info, ebx
401
;           ret
381 serge 402
@@:
403
.fail:
406 serge 404
           or eax, -1
405
           ret
381 serge 406
endp
407
 
408
restore   handle
409
restore   io_code
410
restore   input
411
restore   inp_size
412
restore   output
413
restore   out_size
414
 
415
 
416
align 4
417
proc ac97_irq
418
 
419
;     if DEBUG
420
;           mov esi, msgIRQ
421
;           call SysMsgBoardStr
422
;     end if
423
 
424
 
406 serge 425
           cmp [ctrl.user_callback], 0
426
           je @f
381 serge 427
 
406 serge 428
           stdcall [ctrl.user_callback], ebx
381 serge 429
@@:
406 serge 430
           ret
381 serge 431
 
432
.skip:
406 serge 433
           mov edx, PCM_OUT_CR_REG
434
           mov ax, 0x11               ;0x1D
435
           call [ctrl.ctrl_write8]
436
           ret
381 serge 437
endp
438
 
439
align 4
440
proc create_primary_buff
441
 
442
           stdcall KernelAlloc, 0x10000
406 serge 443
           mov [ctrl.buffer], eax
381 serge 444
 
406 serge 445
           mov edi, eax
446
           mov ecx, 0x10000/4
447
           xor eax, eax
381 serge 448
           cld
406 serge 449
           rep stosd
381 serge 450
 
406 serge 451
           mov eax, [ctrl.buffer]
452
           call GetPgAddr
381 serge 453
 
406 serge 454
           mov ebx, 0xC0002000
455
           mov ecx, 4
456
           mov edi, pcmout_bdl
381 serge 457
@@:
406 serge 458
           mov [edi], eax
459
           mov [edi+4], ebx
381 serge 460
 
406 serge 461
           mov [edi+32], eax
462
           mov [edi+4+32], ebx
381 serge 463
 
406 serge 464
           mov [edi+64], eax
465
           mov [edi+4+64], ebx
381 serge 466
 
406 serge 467
           mov [edi+96], eax
468
           mov [edi+4+96], ebx
381 serge 469
 
406 serge 470
           mov [edi+128], eax
471
           mov [edi+4+128], ebx
381 serge 472
 
406 serge 473
           mov [edi+160], eax
474
           mov [edi+4+160], ebx
381 serge 475
 
406 serge 476
           mov [edi+192], eax
477
           mov [edi+4+192], ebx
381 serge 478
 
406 serge 479
           mov [edi+224], eax
480
           mov [edi+4+224], ebx
381 serge 481
 
406 serge 482
           add eax, 0x4000
483
           add edi, 8
484
           loop @B
381 serge 485
 
406 serge 486
           mov edi, buff_list
487
           mov eax, [ctrl.buffer]
488
           mov ecx, 4
381 serge 489
@@:
406 serge 490
           mov [edi], eax
491
           mov [edi+16], eax
492
           mov [edi+32], eax
493
           mov [edi+48], eax
494
           mov [edi+64], eax
495
           mov [edi+80], eax
496
           mov [edi+96], eax
497
           mov [edi+112], eax
381 serge 498
 
406 serge 499
           add eax, 0x4000
500
           add edi, 4
501
           loop @B
381 serge 502
 
406 serge 503
           mov eax, pcmout_bdl
504
           mov ebx, eax
505
           call GetPgAddr     ;eax
506
           and ebx, 0xFFF
507
           add eax, ebx
381 serge 508
 
406 serge 509
           mov edx, PCM_OUT_BDL
510
           call [ctrl.ctrl_write32]
381 serge 511
 
406 serge 512
           mov eax, 16
513
           mov [ctrl.lvi_reg], eax
514
           mov edx, PCM_OUT_LVI_REG
515
           call [ctrl.ctrl_write8]
516
           ret
381 serge 517
endp
518
 
519
align 4
520
proc detect_controller
406 serge 521
         locals
522
           last_bus dd ?
523
           bus      dd ?
524
           devfn    dd ?
525
         endl
381 serge 526
 
406 serge 527
           xor eax, eax
528
           mov [bus], eax
529
           inc eax
381 serge 530
           call PciApi
406 serge 531
           cmp eax, -1
532
           je .err
381 serge 533
 
406 serge 534
           mov [last_bus], eax
381 serge 535
 
536
.next_bus:
406 serge 537
           and [devfn], 0
381 serge 538
.next_dev:
539
           stdcall PciRead32, [bus], [devfn], dword 0
406 serge 540
           test eax, eax
541
           jz .next
542
           cmp eax, -1
543
           je .next
381 serge 544
 
406 serge 545
           mov edi, devices
381 serge 546
@@:
406 serge 547
           mov ebx, [edi]
548
           test ebx, ebx
549
           jz .next
381 serge 550
 
406 serge 551
           cmp eax, ebx
552
           je .found
553
           add edi, 12
554
           jmp @B
381 serge 555
 
406 serge 556
.next:
557
           inc [devfn]
558
           cmp [devfn], 256
559
           jb  .next_dev
560
           mov eax, [bus]
561
           inc eax
562
           mov [bus], eax
563
           cmp eax, [last_bus]
564
           jna .next_bus
565
           xor eax, eax
566
           ret
381 serge 567
.found:
406 serge 568
           mov ebx, [bus]
569
           mov [ctrl.bus], ebx
381 serge 570
 
406 serge 571
           mov ecx, [devfn]
572
           mov [ctrl.devfn], ecx
381 serge 573
 
406 serge 574
           mov edx, eax
575
           and edx, 0xFFFF
576
           mov [ctrl.vendor], edx
577
           shr eax, 16
578
           mov [ctrl.dev_id], eax
381 serge 579
 
406 serge 580
           mov ebx, [edi+4]
581
           mov [ctrl.ctrl_ids], ebx
582
           mov esi, [edi+8]
583
           mov [ctrl.ctrl_setup], esi
381 serge 584
 
585
           cmp ebx, 0x1274
586
           jne @F
587
           mov [ctrl.vendor_ids], msgEnsoniq
588
           ret
589
@@:
590
           mov [ctrl.vendor_ids], 0     ;something  wrong ?
406 serge 591
           ret
381 serge 592
.err:
406 serge 593
           xor eax, eax
594
           ret
381 serge 595
endp
596
 
597
align 4
406 serge 598
proc init_controller
381 serge 599
 
406 serge 600
           mov esi, msgPCIcmd
601
           call SysMsgBoardStr
381 serge 602
 
406 serge 603
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
604
           mov ebx, eax
605
           and eax, 0xFFFF
606
           mov [ctrl.pci_cmd], eax
607
           shr ebx, 16
608
           mov [ctrl.pci_stat], ebx
381 serge 609
 
406 serge 610
           call dword2str
611
           call SysMsgBoardStr
381 serge 612
 
406 serge 613
           mov esi, msgIObase
614
           call SysMsgBoardStr
381 serge 615
 
616
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
412 serge 617
;           and eax, -16
618
           mov [ctrl.ctrl_io_base], eax
381 serge 619
 
406 serge 620
           call dword2str
621
           call SysMsgBoardStr
381 serge 622
 
412 serge 623
           mov esi, msgIRQline
406 serge 624
           call SysMsgBoardStr
381 serge 625
 
626
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
406 serge 627
           and eax, 0xFF
628
           mov [ctrl.int_line], eax
381 serge 629
 
406 serge 630
           call dword2str
631
           call SysMsgBoardStr
381 serge 632
 
406 serge 633
           call [ctrl.ctrl_setup]
634
           xor eax, eax
635
           inc eax
636
           ret
381 serge 637
endp
638
 
639
align 4
640
proc set_ICH
406 serge 641
           mov [ctrl.codec_read16],  codec_io_r16    ;virtual
642
           mov [ctrl.codec_write16], codec_io_w16    ;virtual
381 serge 643
 
406 serge 644
           mov [ctrl.ctrl_read8 ],  ctrl_io_r8      ;virtual
645
           mov [ctrl.ctrl_read16],  ctrl_io_r16      ;virtual
646
           mov [ctrl.ctrl_read32],  ctrl_io_r32      ;virtual
381 serge 647
 
406 serge 648
           mov [ctrl.ctrl_write8 ], ctrl_io_w8      ;virtual
649
           mov [ctrl.ctrl_write16], ctrl_io_w16      ;virtual
650
           mov [ctrl.ctrl_write32], ctrl_io_w32      ;virtual
651
           ret
381 serge 652
endp
653
 
654
align 4
655
proc reset_controller
656
 
412 serge 657
           xor eax, eax
658
           mov edx, PCM_IN_CR_REG
659
           call [ctrl.ctrl_write8]
381 serge 660
 
412 serge 661
           mov edx, PCM_OUT_CR_REG
662
           call [ctrl.ctrl_write8]
381 serge 663
 
412 serge 664
           mov edx, MC_IN_CR_REG
665
           call [ctrl.ctrl_write8]
381 serge 666
 
412 serge 667
           mov eax, RR
668
           mov edx, PCM_IN_CR_REG
669
           call [ctrl.ctrl_write8]
381 serge 670
 
412 serge 671
           mov edx, PCM_OUT_CR_REG
672
           call [ctrl.ctrl_write8]
381 serge 673
 
412 serge 674
           mov edx, MC_IN_CR_REG
675
           call [ctrl.ctrl_write8]
676
           ret
381 serge 677
endp
678
 
679
align 4
680
proc init_codec
412 serge 681
         locals
682
           counter dd ?
683
         endl
381 serge 684
 
406 serge 685
           mov esi, msgControl
686
           call SysMsgBoardStr
687
 
688
           mov edx, GLOB_CTRL
689
           call [ctrl.ctrl_read32]
690
           call dword2str
691
           call SysMsgBoardStr
692
 
693
           mov esi, msgStatus
694
           call SysMsgBoardStr
695
 
696
           mov edx, CTRL_STAT
697
           call [ctrl.ctrl_read32]
698
 
699
           call dword2str
700
           call SysMsgBoardStr
701
 
702
           test eax, CTRL_ST_CREADY
703
           jnz .ready
704
 
412 serge 705
           call reset_codec
706
           and eax, eax
707
           jz .err
381 serge 708
 
412 serge 709
           xor edx, edx     ;ac_reg_0
710
           call [ctrl.codec_write16]
381 serge 711
 
412 serge 712
           xor eax, eax
713
           mov edx, CODEC_REG_POWERDOWN
714
           call [ctrl.codec_write16]
381 serge 715
 
412 serge 716
           mov [counter], 200     ; total 200*5 ms = 1s
381 serge 717
.wait:
412 serge 718
           mov edx, CODEC_REG_POWERDOWN
719
           call [ctrl.codec_read16]
720
           and eax, 0x0F
721
           cmp eax, 0x0F
722
           jz .ready
381 serge 723
 
412 serge 724
           mov eax, 5000   ; wait 5 ms
725
           call StallExec
726
           sub [counter] , 1
727
           jnz .wait
381 serge 728
.err:
412 serge 729
           xor eax, eax        ; timeout error
730
           ret
381 serge 731
.ready:
412 serge 732
           call detect_codec
381 serge 733
 
412 serge 734
           xor eax, eax
735
           inc eax
736
           ret
381 serge 737
endp
738
 
739
align 4
740
proc reset_codec
406 serge 741
           mov edx, GLOB_CTRL
742
           call [ctrl.ctrl_read32]
381 serge 743
 
744
           test eax, 0x02
745
           jz .cold
746
 
747
           call warm_reset
748
           jnc .ok
749
.cold:
406 serge 750
           call cold_reset
751
           jnc .ok
381 serge 752
 
753
     if DEBUG
406 serge 754
           mov esi, msgCFail
381 serge 755
           call SysMsgBoardStr
756
     end if
406 serge 757
           xor eax, eax     ; timeout error
758
           ret
381 serge 759
.ok:
760
     if DEBUG
761
           mov esi, msgResetOk
762
           call SysMsgBoardStr
763
     end if
764
 
765
           xor eax, eax
406 serge 766
           inc eax
767
           ret
381 serge 768
endp
769
 
770
align 4
771
proc warm_reset
772
	   locals
773
	     counter dd ?
774
	   endl
775
 
776
	   mov eax, 0x06
777
	   mov edx, GLOB_CTRL
778
	   call [ctrl.ctrl_write32]
779
 
780
     if DEBUG
781
	   mov esi, msgWarm
782
           call SysMsgBoardStr
783
     end if
784
 
785
	   mov [counter], 10	   ; total 10*100 ms = 1s
786
.wait:
787
	   mov eax, 100000	   ; wait 100 ms
788
	   call StallExec
789
 
790
	   mov edx, GLOB_CTRL
791
	   call [ctrl.ctrl_read32]
792
	   test eax, 4
793
	   jz .ok
794
	   sub [counter], 1
795
	   jnz .wait
796
 
797
     if DEBUG
798
	   mov esi, msgWRFail
799
           call SysMsgBoardStr
800
     end if
801
 
802
	   stc
803
	   ret
804
.ok:
805
	   mov edx, CTRL_STAT
806
	   call [ctrl.ctrl_read32]
807
	   and eax, CTRL_ST_CREADY
808
           jz .fail
809
           clc
810
	   ret
811
.fail:
812
           stc
813
	   ret
814
endp
815
 
816
align 4
817
proc cold_reset
818
	   locals
819
	     counter dd ?
820
	   endl
821
 
822
	   xor eax, eax
823
	   mov edx, GLOB_CTRL
824
	   call [ctrl.ctrl_write32]
825
 
826
     if DEBUG
827
	   mov esi, msgCold
828
           call SysMsgBoardStr
829
     end if
830
 
831
	   mov eax, 1000000	   ; wait 1 s
832
	   call StallExec
833
 
834
	   mov eax, 2
835
	   mov edx, GLOB_CTRL
836
	   call [ctrl.ctrl_write32]
837
 
838
	   mov [counter], 10	   ; total 10*100 ms = 1s
839
.wait:
840
	   mov eax, 100000	   ; wait 100 ms
841
	   call StallExec
842
 
843
	   mov edx, GLOB_CTRL
844
	   call [ctrl.ctrl_read32]
845
	   test eax, 4
846
	   jz .ok
847
	   sub [counter], 1
848
	   jnz .wait
849
 
850
     if DEBUG
851
	   mov esi, msgCRFail
852
           call SysMsgBoardStr
853
     end if
854
	   stc
855
	   ret
856
.ok:
857
	   mov edx, CTRL_STAT
858
	   call [ctrl.ctrl_read32]
859
	   and eax, CTRL_ST_CREADY
860
           jz .fail
861
           clc
862
	   ret
863
.fail:
864
           stc
865
	   ret
866
endp
867
 
868
align 4
406 serge 869
play:
412 serge 870
           mov eax, 16
871
           mov [ctrl.lvi_reg], eax
872
           mov edx, PCM_OUT_LVI_REG
873
           call [ctrl.ctrl_write8]
381 serge 874
 
412 serge 875
           mov edx, PCM_OUT_CR_REG
876
           mov ax, 0x1D
877
           call [ctrl.ctrl_write8]
406 serge 878
           xor eax, eax
412 serge 879
           ret
381 serge 880
 
881
align 4
406 serge 882
stop:
412 serge 883
           mov edx, PCM_OUT_CR_REG
406 serge 884
           mov ax, 0x0
412 serge 885
           call [ctrl.ctrl_write8]
381 serge 886
 
406 serge 887
           mov ax, 0x1c
888
           mov edx, PCM_OUT_SR_REG
889
           call [ctrl.ctrl_write16]
890
           xor eax, eax
381 serge 891
	   ret
892
 
893
align 4
894
proc get_dev_info stdcall, p_info:dword
895
	   virtual at esi
896
	     CTRL_INFO CTRL_INFO
897
	   end virtual
898
 
899
	   mov esi, [p_info]
900
	   mov eax, [ctrl.int_line]
901
	   mov ebx, [ctrl.codec_io_base]
902
	   mov ecx, [ctrl.ctrl_io_base]
903
	   mov edx, [ctrl.codec_mem_base]
904
	   mov edi, [ctrl.ctrl_mem_base]
905
 
906
	   mov [CTRL_INFO.irq], eax
907
	   mov [CTRL_INFO.codec_io_base], ebx
908
	   mov [CTRL_INFO.ctrl_io_base], ecx
909
	   mov [CTRL_INFO.codec_mem_base], edx
910
	   mov [CTRL_INFO.ctrl_mem_base], edi
911
 
912
           mov eax, [codec.chip_id]
913
           mov [CTRL_INFO.codec_id], eax
914
 
915
	   mov edx, GLOB_CTRL
916
           call [ctrl.ctrl_read32]
917
	   mov [CTRL_INFO.glob_cntrl], eax
918
 
919
	   mov edx, CTRL_STAT
920
           call [ctrl.ctrl_read32]
921
	   mov [CTRL_INFO.glob_sta], eax
922
 
923
	   mov ebx, [ctrl.pci_cmd]
924
	   mov [CTRL_INFO.pci_cmd], ebx
925
	   ret
926
endp
927
 
928
align 4
929
proc set_callback stdcall, handler:dword
930
	   mov eax, [handler]
931
	   mov [ctrl.user_callback], eax
932
	   ret
933
endp
934
 
935
align 4
936
proc codec_read stdcall, ac_reg:dword	   ; reg = edx, reval = eax
937
 
938
	   mov edx, [ac_reg]
939
 
940
	   mov ebx, edx
941
	   shr ebx, 1
942
	   bt [codec.shadow_flag], ebx
943
	   jc .use_shadow
944
 
945
	   call [ctrl.codec_read16]  ;change edx !!!
946
	   mov ecx, eax
947
 
948
	   mov edx, CTRL_STAT
949
	   call [ctrl.ctrl_read32]
950
	   test eax, CTRL_ST_RCS
951
	   jz .read_ok
952
 
953
	   mov edx, CTRL_STAT
954
	   call [ctrl.ctrl_write32]
955
	   xor eax,eax
956
	   not eax		;timeout
957
	   ret
958
.read_ok:
959
	   mov edx, [ac_reg]
960
	   mov [codec.regs+edx], cx
961
	   bts [codec.shadow_flag], ebx
962
	   mov eax, ecx
963
	   ret
964
.use_shadow:
965
	   movzx eax, word [codec.regs+edx]
966
	   ret
967
endp
968
 
969
align 4
970
proc codec_write stdcall, ac_reg:dword
971
	   push eax
972
	   call check_semafore
973
	   and eax, eax
974
	   jz .err
975
	   pop eax
976
 
977
	   mov esi, [ac_reg]
978
	   mov edx, esi
979
	   call [ctrl.codec_write16]
980
	   mov [codec.regs+esi], ax
981
	   shr esi, 1
982
	   bts [codec.shadow_flag], esi
983
	   ret
984
.err:
985
	   pop eax
986
	   ret
987
endp
988
 
989
align 4
990
proc codec_check_ready
991
 
412 serge 992
           mov edx, CTRL_ST
993
           call [ctrl.ctrl_read32]
994
           and eax, CTRL_ST_CREADY
995
           jz .not_ready
381 serge 996
 
412 serge 997
           xor eax, wax
998
           inc eax
999
           ret
381 serge 1000
.not_ready:
412 serge 1001
           xor eax, eax
1002
           ret
381 serge 1003
endp
1004
 
1005
align 4
1006
proc check_semafore
1007
	   local counter:DWORD
1008
 
1009
	   mov [counter], 100
1010
.l1:
1011
	   mov edx, CTRL_CAS
1012
	   call [ctrl.ctrl_read8]
1013
	   and eax, CAS_FLAG
1014
	   jz .ok
1015
 
1016
	   mov eax, 1
1017
	   call StallExec
1018
	   sub [counter], 1
1019
	   jnz .l1
1020
	   xor eax, eax
1021
	   ret
1022
align 4
1023
.ok:
1024
	   xor eax,eax
1025
	   inc eax
1026
	   ret
1027
endp
1028
 
1029
align 4
1030
proc StallExec
1031
	   push ecx
1032
	   push edx
1033
	   push ebx
1034
	   push eax
1035
 
1036
	   mov ecx, CPU_FREQ
1037
	   mul ecx
1038
	   mov ebx, eax       ;low
1039
	   mov ecx, edx       ;high
1040
	   rdtsc
1041
	   add ebx, eax
1042
	   adc ecx,edx
1043
@@:
1044
	   rdtsc
1045
	   sub eax, ebx
1046
	   sbb edx, ecx
406 serge 1047
           js @B
381 serge 1048
 
1049
	   pop eax
1050
	   pop ebx
1051
	   pop edx
1052
	   pop ecx
1053
	   ret
1054
endp
1055
 
1056
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1057
;          CONTROLLER IO functions
1058
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1059
 
1060
align 4
412 serge 1061
codec_io_r16:
406 serge 1062
           add edx, [ctrl.codec_io_base]
1063
           in  ax, dx
1064
           ret
381 serge 1065
 
1066
align 4
412 serge 1067
codec_io_w16:
406 serge 1068
           add edx, [ctrl.codec_io_base]
1069
           out dx, ax
1070
           ret
381 serge 1071
 
1072
align 4
412 serge 1073
ctrl_io_r8:
406 serge 1074
           add edx, [ctrl.ctrl_io_base]
1075
           in  al, dx
1076
           ret
381 serge 1077
 
1078
align 4
412 serge 1079
ctrl_io_r16:
1080
          add edx, [ctrl.ctrl_io_base]
1081
          in  ax, dx
1082
          ret
381 serge 1083
 
1084
align 4
412 serge 1085
ctrl_io_r32:
1086
          add edx, [ctrl.ctrl_io_base]
1087
          in  eax, dx
1088
          ret
381 serge 1089
 
1090
align 4
412 serge 1091
ctrl_io_w8:
1092
          add edx, [ctrl.ctrl_io_base]
1093
          out dx, al
1094
          ret
381 serge 1095
 
1096
align 4
412 serge 1097
ctrl_io_w16:
1098
          add edx, [ctrl.ctrl_io_base]
1099
          out dx, ax
1100
          ret
381 serge 1101
 
1102
align 4
412 serge 1103
ctrl_io_w32:
1104
          add edx, [ctrl.ctrl_io_base]
1105
          out dx, eax
1106
          ret
381 serge 1107
 
1108
 
1109
align 4
406 serge 1110
dword2str:
412 serge 1111
          mov  esi, hex_buff
1112
          mov ecx, -8
406 serge 1113
@@:
412 serge 1114
          rol eax, 4
1115
          mov ebx, eax
1116
          and ebx, 0x0F
1117
          mov bl, [ebx+hexletters]
1118
          mov [8+esi+ecx], bl
1119
          inc ecx
1120
          jnz @B
1121
          ret
381 serge 1122
 
406 serge 1123
hexletters   db '0123456789ABCDEF'
1124
hex_buff     db 8 dup(0),13,10,0
381 serge 1125
 
1126
 
1127
include "codec.inc"
1128
 
1129
align 4
412 serge 1130
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH
1131
        dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH
1132
        dd 0    ;terminator
381 serge 1133
 
412 serge 1134
version      dd 0x00040004
381 serge 1135
 
412 serge 1136
msgEnsoniq   db 'Ensonic 1371',13,10,0
1137
msgVibra128  db 'Sound Blaster AudioPCI Vibra 128',13,10,0
381 serge 1138
 
406 serge 1139
sz_sound_srv db 'SOUND',0
381 serge 1140
 
406 serge 1141
msgDetect    db 'detect hardware...',13,10,0
381 serge 1142
msgFail      db 'device not found',13,10,0
1143
msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
1144
msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
1145
msgPlay      db 'start play', 13,10,0
1146
msgStop      db 'stop play',  13,10,0
1147
msgNotify    db 'call notify',13,10,0
406 serge 1148
msgIRQ       db 'AC97 IRQ', 13,10,0
381 serge 1149
msgInitCtrl  db 'init controller',13,10,0
1150
msgInitCodec db 'init codec',13,10,0
1151
msgPrimBuff  db 'create primary buffer',13,10,0
406 serge 1152
msgReg       db 'set service handler',13,10,0
1153
msgOk        db 'service installed',13,10,0
381 serge 1154
msgCold      db 'cold reset',13,10,0
1155
msgWarm      db 'warm reset',13,10,0
1156
msgWRFail    db 'warm reset failed',13,10,0
1157
msgCRFail    db 'cold reset failed',13,10,0
1158
msgCFail     db 'codec not ready',13,10,0
1159
msgResetOk   db 'reset complete',13,10,0
406 serge 1160
msgStatus    db 'global status   ',0
1161
msgControl   db 'global control  ',0
1162
msgPCIcmd    db 'PCI command     ',0
1163
msgIObase    db 'IO base         ',0
412 serge 1164
msgIRQline   db 'IRQ line        ',0
381 serge 1165
 
1166
section '.data' data readable writable align 16
1167
 
1168
pcmout_bdl       rq 32
1169
buff_list        rd 32
1170
 
1171
codec CODEC
1172
ctrl AC_CNTRL
1173
 
1174
lpc_bus  rd 1
1175
civ_val  rd 1
1176