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