Subversion Repositories Kolibri OS

Rev

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