Subversion Repositories Kolibri OS

Rev

Rev 774 | 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
 
802 serge 12
DEBUG	    equ 1
381 serge 13
 
802 serge 14
 
381 serge 15
include 'proc32.inc'
406 serge 16
include 'imports.inc'
381 serge 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
774 Rus 112
{ .bus		      dd ?
113
  .devfn	      dd ?
381 serge 114
 
774 Rus 115
  .vendor	      dd ?
116
  .dev_id	      dd ?
117
  .pci_cmd	      dd ?
118
  .pci_stat	      dd ?
381 serge 119
 
120
  .codec_io_base      dd ?
121
  .codec_mem_base     dd ?
122
 
123
  .ctrl_io_base       dd ?
124
  .ctrl_mem_base      dd ?
774 Rus 125
  .cfg_reg	      dd ?
126
  .int_line	      dd ?
381 serge 127
 
774 Rus 128
  .vendor_ids	      dd ?    ;vendor id string
129
  .ctrl_ids	      dd ?    ;hub id string
381 serge 130
 
774 Rus 131
  .buffer	      dd ?
381 serge 132
 
774 Rus 133
  .notify_pos	      dd ?
134
  .notify_task	      dd ?
381 serge 135
 
774 Rus 136
  .lvi_reg	      dd ?
137
  .ctrl_setup	      dd ?
381 serge 138
  .user_callback      dd ?
139
  .codec_read16       dd ?
140
  .codec_write16      dd ?
141
 
774 Rus 142
  .ctrl_read8	      dd ?
143
  .ctrl_read16	      dd ?
144
  .ctrl_read32	      dd ?
381 serge 145
 
774 Rus 146
  .ctrl_write8	      dd ?
381 serge 147
  .ctrl_write16       dd ?
148
  .ctrl_write32       dd ?
149
}
150
 
151
struc CODEC		   ;Audio Chip base class
152
{
774 Rus 153
  .chip_id	      dd ?
154
  .flags	      dd ?
155
  .status	      dd ?
381 serge 156
 
157
  .ac_vendor_ids      dd ?    ;ac vendor id string
774 Rus 158
  .chip_ids	      dd ?    ;chip model string
381 serge 159
 
774 Rus 160
  .shadow_flag	      dd ?
161
		      dd ?
381 serge 162
 
774 Rus 163
  .regs 	      dw ?     ; codec registers
381 serge 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
774 Rus 170
  .reg_mic_vol	      dw ?     ;0x0E
381 serge 171
  .reg_line_in_vol    dw ?     ;0x10
774 Rus 172
  .reg_cd_vol	      dw ?     ;0x12
381 serge 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
774 Rus 179
  .reg_gen	      dw ?     ;0x20
180
  .reg_3d_ctrl	      dw ?     ;0X22
181
  .reg_page	      dw ?     ;0X24
381 serge 182
  .reg_powerdown      dw ?     ;0x26
183
  .reg_ext_audio      dw ?     ;0x28
774 Rus 184
  .reg_ext_st	      dw ?     ;0x2a
381 serge 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
774 Rus 189
		      dw ?     ;0x34
381 serge 190
  .reg_cent_lfe_vol   dw ?     ;0x36
191
  .reg_surr_vol       dw ?     ;0x38
192
  .reg_spdif_ctrl     dw ?     ;0x3A
774 Rus 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
381 serge 225
  .reg_vendor_id_1    dw ?     ;0x7C
226
  .reg_vendor_id_2    dw ?     ;0x7E
227
 
228
 
774 Rus 229
  .reset	      dd ?    ;virual
381 serge 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	?
774 Rus 242
    .codec_id	    dd	?
381 serge 243
}
244
 
245
struc IOCTL
774 Rus 246
{  .handle	     dd ?
247
   .io_code	     dd ?
248
   .input	     dd ?
249
   .inp_size	     dd ?
250
   .output	     dd ?
251
   .out_size	     dd ?
381 serge 252
}
253
 
254
virtual at 0
255
  IOCTL IOCTL
256
end virtual
257
 
258
EVENT_NOTIFY	      equ 0x00000200
259
 
774 Rus 260
OS_BASE 	equ 0x80000000
261
SLOT_BASE	equ OS_BASE+0x0080000
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
 
774 Rus 272
	   cmp [state], 1
273
	   jne .stop
406 serge 274
 
381 serge 275
     if DEBUG
774 Rus 276
	   mov esi, msgDetect
277
	   call SysMsgBoardStr
381 serge 278
     end if
279
 
774 Rus 280
	   call detect_controller
281
	   test eax, eax
282
	   jz .fail
381 serge 283
 
284
     if DEBUG
774 Rus 285
	   mov esi,[ctrl.vendor_ids]
286
	   call SysMsgBoardStr
287
	   mov	 esi, [ctrl.ctrl_ids]
288
	   call SysMsgBoardStr
381 serge 289
 
290
     end if
774 Rus 291
	   call init_controller
292
	   test eax, eax
293
	   jz .fail
381 serge 294
 
774 Rus 295
	   jmp .fail	  ;force fail
406 serge 296
 
381 serge 297
     if DEBUG
774 Rus 298
	   mov esi, msgInitCodec
299
	   call SysMsgBoardStr
381 serge 300
     end if
301
 
774 Rus 302
	   call init_codec
303
	   test eax, eax
304
	   jz .fail
381 serge 305
 
306
     if DEBUG
774 Rus 307
	   mov esi, [codec.ac_vendor_ids]
308
	   call SysMsgBoardStr
381 serge 309
 
774 Rus 310
	   mov esi, [codec.chip_ids]
311
	   call SysMsgBoardStr
381 serge 312
     end if
313
 
774 Rus 314
	   call reset_controller
315
	   call setup_codec
381 serge 316
 
774 Rus 317
	   mov esi, msgPrimBuff
318
	   call SysMsgBoardStr
381 serge 319
 
774 Rus 320
	   call create_primary_buff
381 serge 321
 
774 Rus 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
381 serge 331
 
774 Rus 332
	   stdcall AttachIntHandler, ebx, ac97_irq, dword 0
333
	   stdcall RegService, sz_sound_srv, service_proc
381 serge 334
	   ret
335
.fail:
336
     if DEBUG
774 Rus 337
	   mov esi, msgFail
338
	   call SysMsgBoardStr
381 serge 339
     end if
774 Rus 340
	   xor eax, eax
341
	   ret
406 serge 342
.stop:
774 Rus 343
	   call stop
344
	   xor eax, eax
345
	   ret
406 serge 346
endp
381 serge 347
 
774 Rus 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
381 serge 354
 
355
align 4
356
proc service_proc stdcall, ioctl:dword
357
 
774 Rus 358
	   mov edi, [ioctl]
359
	   mov eax, [edi+io_code]
360
	   cmp eax, DEV_PLAY
361
	   jne @F
381 serge 362
     if DEBUG
774 Rus 363
	   mov esi, msgPlay
364
	   call SysMsgBoardStr
381 serge 365
     end if
774 Rus 366
	   call play
367
	   ret
381 serge 368
@@:
774 Rus 369
	   cmp eax, DEV_STOP
370
	   jne @F
381 serge 371
     if DEBUG
774 Rus 372
	   mov esi, msgStop
373
	   call SysMsgBoardStr
381 serge 374
     end if
774 Rus 375
	   call stop
376
	   ret
381 serge 377
@@:
774 Rus 378
	   cmp eax, DEV_CALLBACK
379
	   jne @F
380
	   mov ebx, [edi+input]
381
	   stdcall set_callback, [ebx]
382
	   ret
381 serge 383
@@:
774 Rus 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
@@:
774 Rus 391
	   cmp eax, DEV_GET_MASTERVOL
392
	   jne @F
393
	   mov ebx, [edi+output]
394
	   stdcall get_master_vol, ebx
395
	   ret
406 serge 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:
774 Rus 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
 
774 Rus 425
	   cmp [ctrl.user_callback], 0
426
	   je @f
381 serge 427
 
774 Rus 428
	   stdcall [ctrl.user_callback], ebx
381 serge 429
@@:
774 Rus 430
	   ret
381 serge 431
 
432
.skip:
774 Rus 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
 
774 Rus 442
	   stdcall KernelAlloc, 0x10000
443
	   mov [ctrl.buffer], eax
381 serge 444
 
774 Rus 445
	   mov edi, eax
446
	   mov ecx, 0x10000/4
447
	   xor eax, eax
448
	   cld
449
	   rep stosd
381 serge 450
 
774 Rus 451
	   mov eax, [ctrl.buffer]
452
	   call GetPgAddr
381 serge 453
 
774 Rus 454
	   mov ebx, 0xC0002000
455
	   mov ecx, 4
456
	   mov edi, pcmout_bdl
381 serge 457
@@:
774 Rus 458
	   mov [edi], eax
459
	   mov [edi+4], ebx
381 serge 460
 
774 Rus 461
	   mov [edi+32], eax
462
	   mov [edi+4+32], ebx
381 serge 463
 
774 Rus 464
	   mov [edi+64], eax
465
	   mov [edi+4+64], ebx
381 serge 466
 
774 Rus 467
	   mov [edi+96], eax
468
	   mov [edi+4+96], ebx
381 serge 469
 
774 Rus 470
	   mov [edi+128], eax
471
	   mov [edi+4+128], ebx
381 serge 472
 
774 Rus 473
	   mov [edi+160], eax
474
	   mov [edi+4+160], ebx
381 serge 475
 
774 Rus 476
	   mov [edi+192], eax
477
	   mov [edi+4+192], ebx
381 serge 478
 
774 Rus 479
	   mov [edi+224], eax
480
	   mov [edi+4+224], ebx
381 serge 481
 
774 Rus 482
	   add eax, 0x4000
483
	   add edi, 8
484
	   loop @B
381 serge 485
 
774 Rus 486
	   mov edi, buff_list
487
	   mov eax, [ctrl.buffer]
488
	   mov ecx, 4
381 serge 489
@@:
774 Rus 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
 
774 Rus 499
	   add eax, 0x4000
500
	   add edi, 4
501
	   loop @B
381 serge 502
 
774 Rus 503
	   mov eax, pcmout_bdl
504
	   mov ebx, eax
505
	   call GetPgAddr     ;eax
506
	   and ebx, 0xFFF
507
	   add eax, ebx
381 serge 508
 
774 Rus 509
	   mov edx, PCM_OUT_BDL
510
	   call [ctrl.ctrl_write32]
381 serge 511
 
774 Rus 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
774 Rus 521
	 locals
522
	   last_bus dd ?
523
	   bus	    dd ?
524
	   devfn    dd ?
525
	 endl
381 serge 526
 
774 Rus 527
	   xor eax, eax
528
	   mov [bus], eax
529
	   inc eax
530
	   call PciApi
531
	   cmp eax, -1
532
	   je .err
381 serge 533
 
774 Rus 534
	   mov [last_bus], eax
381 serge 535
 
536
.next_bus:
774 Rus 537
	   and [devfn], 0
381 serge 538
.next_dev:
774 Rus 539
	   stdcall PciRead32, [bus], [devfn], dword 0
540
	   test eax, eax
541
	   jz .next
542
	   cmp eax, -1
543
	   je .next
381 serge 544
 
774 Rus 545
	   mov edi, devices
381 serge 546
@@:
774 Rus 547
	   mov ebx, [edi]
548
	   test ebx, ebx
549
	   jz .next
381 serge 550
 
774 Rus 551
	   cmp eax, ebx
552
	   je .found
553
	   add edi, 12
554
	   jmp @B
381 serge 555
 
406 serge 556
.next:
774 Rus 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:
774 Rus 568
	   mov ebx, [bus]
569
	   mov [ctrl.bus], ebx
381 serge 570
 
774 Rus 571
	   mov ecx, [devfn]
572
	   mov [ctrl.devfn], ecx
381 serge 573
 
774 Rus 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
 
774 Rus 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
 
774 Rus 585
	   cmp ebx, 0x1274
586
	   jne @F
587
	   mov [ctrl.vendor_ids], msgEnsoniq
588
	   ret
381 serge 589
@@:
774 Rus 590
	   mov [ctrl.vendor_ids], 0	;something  wrong ?
591
	   ret
381 serge 592
.err:
774 Rus 593
	   xor eax, eax
594
	   ret
381 serge 595
endp
596
 
597
align 4
406 serge 598
proc init_controller
381 serge 599
 
774 Rus 600
	   mov esi, msgPCIcmd
601
	   call SysMsgBoardStr
381 serge 602
 
774 Rus 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
 
774 Rus 610
	   call dword2str
611
	   call SysMsgBoardStr
381 serge 612
 
774 Rus 613
	   mov esi, msgIObase
614
	   call SysMsgBoardStr
381 serge 615
 
774 Rus 616
	   stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
412 serge 617
;           and eax, -16
774 Rus 618
	   mov [ctrl.ctrl_io_base], eax
381 serge 619
 
774 Rus 620
	   call dword2str
621
	   call SysMsgBoardStr
381 serge 622
 
774 Rus 623
	   mov esi, msgIRQline
624
	   call SysMsgBoardStr
381 serge 625
 
774 Rus 626
	   stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
627
	   and eax, 0xFF
628
	   mov [ctrl.int_line], eax
381 serge 629
 
774 Rus 630
	   call dword2str
631
	   call SysMsgBoardStr
381 serge 632
 
774 Rus 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
774 Rus 641
	   mov [ctrl.codec_read16],  codec_io_r16    ;virtual
642
	   mov [ctrl.codec_write16], codec_io_w16    ;virtual
381 serge 643
 
774 Rus 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
 
774 Rus 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
 
774 Rus 657
	   xor eax, eax
658
	   mov edx, PCM_IN_CR_REG
659
	   call [ctrl.ctrl_write8]
381 serge 660
 
774 Rus 661
	   mov edx, PCM_OUT_CR_REG
662
	   call [ctrl.ctrl_write8]
381 serge 663
 
774 Rus 664
	   mov edx, MC_IN_CR_REG
665
	   call [ctrl.ctrl_write8]
381 serge 666
 
774 Rus 667
	   mov eax, RR
668
	   mov edx, PCM_IN_CR_REG
669
	   call [ctrl.ctrl_write8]
381 serge 670
 
774 Rus 671
	   mov edx, PCM_OUT_CR_REG
672
	   call [ctrl.ctrl_write8]
381 serge 673
 
774 Rus 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
774 Rus 681
	 locals
682
	   counter dd ?
683
	 endl
381 serge 684
 
774 Rus 685
	   mov esi, msgControl
686
	   call SysMsgBoardStr
406 serge 687
 
774 Rus 688
	   mov edx, GLOB_CTRL
689
	   call [ctrl.ctrl_read32]
690
	   call dword2str
691
	   call SysMsgBoardStr
406 serge 692
 
774 Rus 693
	   mov esi, msgStatus
694
	   call SysMsgBoardStr
406 serge 695
 
774 Rus 696
	   mov edx, CTRL_STAT
697
	   call [ctrl.ctrl_read32]
406 serge 698
 
774 Rus 699
	   call dword2str
700
	   call SysMsgBoardStr
406 serge 701
 
774 Rus 702
	   test eax, CTRL_ST_CREADY
703
	   jnz .ready
406 serge 704
 
774 Rus 705
	   call reset_codec
706
	   and eax, eax
707
	   jz .err
381 serge 708
 
774 Rus 709
	   xor edx, edx     ;ac_reg_0
710
	   call [ctrl.codec_write16]
381 serge 711
 
774 Rus 712
	   xor eax, eax
713
	   mov edx, CODEC_REG_POWERDOWN
714
	   call [ctrl.codec_write16]
381 serge 715
 
774 Rus 716
	   mov [counter], 200	  ; total 200*5 ms = 1s
381 serge 717
.wait:
774 Rus 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
 
774 Rus 724
	   mov eax, 5000   ; wait 5 ms
725
	   call StallExec
726
	   sub [counter] , 1
727
	   jnz .wait
381 serge 728
.err:
774 Rus 729
	   xor eax, eax        ; timeout error
730
	   ret
381 serge 731
.ready:
774 Rus 732
	   call detect_codec
381 serge 733
 
774 Rus 734
	   xor eax, eax
735
	   inc eax
736
	   ret
381 serge 737
endp
738
 
739
align 4
740
proc reset_codec
774 Rus 741
	   mov edx, GLOB_CTRL
742
	   call [ctrl.ctrl_read32]
381 serge 743
 
774 Rus 744
	   test eax, 0x02
745
	   jz .cold
381 serge 746
 
774 Rus 747
	   call warm_reset
748
	   jnc .ok
381 serge 749
.cold:
774 Rus 750
	   call cold_reset
751
	   jnc .ok
381 serge 752
 
753
     if DEBUG
774 Rus 754
	   mov esi, msgCFail
755
	   call SysMsgBoardStr
381 serge 756
     end if
774 Rus 757
	   xor eax, eax     ; timeout error
758
	   ret
381 serge 759
.ok:
760
     if DEBUG
774 Rus 761
	   mov esi, msgResetOk
762
	   call SysMsgBoardStr
381 serge 763
     end if
764
 
774 Rus 765
	   xor eax, eax
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
774 Rus 782
	   call SysMsgBoardStr
381 serge 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
774 Rus 799
	   call SysMsgBoardStr
381 serge 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
774 Rus 808
	   jz .fail
809
	   clc
381 serge 810
	   ret
811
.fail:
774 Rus 812
	   stc
381 serge 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
774 Rus 828
	   call SysMsgBoardStr
381 serge 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
774 Rus 852
	   call SysMsgBoardStr
381 serge 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
774 Rus 860
	   jz .fail
861
	   clc
381 serge 862
	   ret
863
.fail:
774 Rus 864
	   stc
381 serge 865
	   ret
866
endp
867
 
868
align 4
406 serge 869
play:
774 Rus 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
 
774 Rus 875
	   mov edx, PCM_OUT_CR_REG
876
	   mov ax, 0x1D
877
	   call [ctrl.ctrl_write8]
878
	   xor eax, eax
879
	   ret
381 serge 880
 
881
align 4
406 serge 882
stop:
774 Rus 883
	   mov edx, PCM_OUT_CR_REG
884
	   mov ax, 0x0
885
	   call [ctrl.ctrl_write8]
381 serge 886
 
774 Rus 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
 
774 Rus 912
	   mov eax, [codec.chip_id]
913
	   mov [CTRL_INFO.codec_id], eax
381 serge 914
 
915
	   mov edx, GLOB_CTRL
774 Rus 916
	   call [ctrl.ctrl_read32]
381 serge 917
	   mov [CTRL_INFO.glob_cntrl], eax
918
 
919
	   mov edx, CTRL_STAT
774 Rus 920
	   call [ctrl.ctrl_read32]
381 serge 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
 
774 Rus 992
	   mov edx, CTRL_ST
993
	   call [ctrl.ctrl_read32]
994
	   and eax, CTRL_ST_CREADY
995
	   jz .not_ready
381 serge 996
 
774 Rus 997
	   xor eax, wax
998
	   inc eax
999
	   ret
381 serge 1000
.not_ready:
774 Rus 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
774 Rus 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:
774 Rus 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:
774 Rus 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:
774 Rus 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:
774 Rus 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:
774 Rus 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:
774 Rus 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:
774 Rus 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:
774 Rus 1104
	  add edx, [ctrl.ctrl_io_base]
1105
	  out dx, eax
1106
	  ret
381 serge 1107
 
1108
 
1109
align 4
406 serge 1110
dword2str:
774 Rus 1111
	  mov  esi, hex_buff
1112
	  mov ecx, -8
406 serge 1113
@@:
774 Rus 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
774 Rus 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
774 Rus 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
774 Rus 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
 
774 Rus 1168
pcmout_bdl	 rq 32
1169
buff_list	 rd 32
381 serge 1170
 
1171
codec CODEC
1172
ctrl AC_CNTRL
1173
 
1174
lpc_bus  rd 1
1175
civ_val  rd 1
1176