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
 
591
	   ret
592
endp
593
 
594
align 4
595
proc detect_controller
227 serge 596
           locals
597
             last_bus dd ?
598
             bus      dd ?
599
             devfn    dd ?
600
           endl
168 serge 601
 
227 serge 602
           xor eax, eax
603
           mov [bus], eax
604
           inc eax
188 serge 605
           call PciApi
227 serge 606
           cmp eax, -1
607
           je .err
168 serge 608
 
609
           mov [last_bus], eax
610
 
611
.next_bus:
227 serge 612
           and [devfn], 0
168 serge 613
.next_dev:
188 serge 614
           stdcall PciRead32, [bus], [devfn], dword 0
227 serge 615
           test eax, eax
616
           jz .next
617
           cmp eax, -1
618
           je .next
579 serge 619
 
227 serge 620
           mov edi, devices
168 serge 621
@@:
227 serge 622
           mov ebx, [edi]
623
           test ebx, ebx
624
           jz .next
168 serge 625
 
227 serge 626
           cmp eax, ebx
627
           je .found
628
           add edi, 12
629
           jmp @B
630
.next:
631
           inc [devfn]
632
           cmp [devfn], 256
633
           jb  .next_dev
634
           mov eax, [bus]
635
           inc eax
636
           mov [bus], eax
637
           cmp eax, [last_bus]
638
           jna .next_bus
639
           xor eax, eax
640
           ret
168 serge 641
.found:
227 serge 642
           mov ebx, [bus]
643
           mov [ctrl.bus], ebx
168 serge 644
 
227 serge 645
           mov ecx, [devfn]
646
           mov [ctrl.devfn], ecx
168 serge 647
 
227 serge 648
           mov edx, eax
649
           and edx, 0xFFFF
650
           mov [ctrl.vendor], edx
651
           shr eax, 16
652
           mov [ctrl.dev_id], eax
168 serge 653
 
227 serge 654
           mov ebx, [edi+4]
655
           mov [ctrl.ctrl_ids], ebx
656
           mov [ctrl.vendor_ids], msg_SIS
168 serge 657
 
227 serge 658
           mov esi, [edi+8]
659
           mov [ctrl.ctrl_setup], esi
660
           ret
168 serge 661
.err:
227 serge 662
           xor eax, eax
663
           ret
168 serge 664
endp
665
 
666
align 4
667
proc init_controller
668
 
188 serge 669
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
227 serge 670
           mov ebx, eax
671
           and eax, 0xFFFF
672
           mov [ctrl.pci_cmd], eax
673
           shr ebx, 16
674
           mov [ctrl.pci_stat], ebx
168 serge 675
 
579 serge 676
           mov esi, msgPciCmd
677
           call SysMsgBoardStr
678
           call dword2str
679
           call SysMsgBoardStr
680
 
681
           mov esi, msgPciStat
682
           call SysMsgBoardStr
683
           mov eax, [ctrl.pci_stat]
684
           call dword2str
685
           call SysMsgBoardStr
686
 
687
           mov esi, msgMixIsaIo
688
           call SysMsgBoardStr
689
 
188 serge 690
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
579 serge 691
 
692
           call dword2str
693
           call SysMsgBoardStr
694
 
227 serge 695
           and eax,0xFFFE
696
           mov [ctrl.codec_io_base], eax
168 serge 697
 
579 serge 698
           mov esi, msgCtrlIsaIo
699
           call SysMsgBoardStr
700
 
188 serge 701
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
579 serge 702
 
703
           call dword2str
704
           call SysMsgBoardStr
705
 
227 serge 706
           and eax, 0xFFC0
707
           mov [ctrl.ctrl_io_base], eax
168 serge 708
 
579 serge 709
           mov esi, msgMixMMIo
710
           call SysMsgBoardStr
711
 
188 serge 712
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
227 serge 713
           mov [ctrl.codec_mem_base], eax
168 serge 714
 
579 serge 715
           call dword2str
716
           call SysMsgBoardStr
717
 
718
           mov esi, msgCtrlMMIo
719
           call SysMsgBoardStr
720
 
188 serge 721
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
227 serge 722
           mov [ctrl.ctrl_mem_base], eax
168 serge 723
 
579 serge 724
           call dword2str
725
           call SysMsgBoardStr
726
.default:
188 serge 727
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
227 serge 728
           and eax, 0xFF
579 serge 729
@@:
227 serge 730
           mov [ctrl.int_line], eax
168 serge 731
 
188 serge 732
           stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41
227 serge 733
           and eax, 0xFF
734
           mov [ctrl.cfg_reg], eax
168 serge 735
 
227 serge 736
           call [ctrl.ctrl_setup]
737
           xor eax, eax
738
           inc eax
739
           ret
168 serge 740
endp
741
 
742
align 4
743
proc set_SIS
227 serge 744
           mov [ctrl.codec_read16],  codec_io_r16    ;virtual
745
           mov [ctrl.codec_write16], codec_io_w16    ;virtual
168 serge 746
 
227 serge 747
           mov [ctrl.ctrl_read8 ],  ctrl_io_r8      ;virtual
748
           mov [ctrl.ctrl_read16],  ctrl_io_r16      ;virtual
749
           mov [ctrl.ctrl_read32],  ctrl_io_r32      ;virtual
168 serge 750
 
227 serge 751
           mov [ctrl.ctrl_write8 ], ctrl_io_w8      ;virtual
752
           mov [ctrl.ctrl_write16], ctrl_io_w16      ;virtual
753
           mov [ctrl.ctrl_write32], ctrl_io_w32      ;virtual
754
           ret
168 serge 755
endp
756
 
757
align 4
758
proc reset_controller
759
 
227 serge 760
           xor eax, eax
761
           mov edx, PCM_IN_CR_REG
762
           call [ctrl.ctrl_write8]
168 serge 763
 
227 serge 764
           mov edx, PCM_OUT_CR_REG
765
           call [ctrl.ctrl_write8]
168 serge 766
 
227 serge 767
           mov edx, MC_IN_CR_REG
768
           call [ctrl.ctrl_write8]
168 serge 769
 
227 serge 770
           mov eax, RR
771
           mov edx, PCM_IN_CR_REG
772
           call [ctrl.ctrl_write8]
168 serge 773
 
227 serge 774
           mov edx, PCM_OUT_CR_REG
775
           call [ctrl.ctrl_write8]
168 serge 776
 
227 serge 777
           mov edx, MC_IN_CR_REG
778
           call [ctrl.ctrl_write8]
779
           ret
168 serge 780
endp
781
 
782
align 4
783
proc init_codec
233 serge 784
           locals
785
             counter dd ?
786
           endl
168 serge 787
 
247 serge 788
           mov esi, msgControl
789
           call SysMsgBoardStr
790
 
791
           mov edx, GLOB_CTRL
792
           call [ctrl.ctrl_read32]
793
           call dword2str
794
           call SysMsgBoardStr
795
 
796
           mov esi, msgStatus
797
           call SysMsgBoardStr
798
 
233 serge 799
           mov edx, CTRL_STAT
800
           call [ctrl.ctrl_read32]
579 serge 801
           push eax
247 serge 802
           call dword2str
803
           call SysMsgBoardStr
579 serge 804
           pop eax
805
           cmp eax, 0xFFFFFFFF
806
           je .err
247 serge 807
 
233 serge 808
           test eax, CTRL_ST_CREADY
809
           jnz .ready
168 serge 810
 
233 serge 811
           call reset_codec
579 serge 812
           test eax, eax
233 serge 813
           jz .err
168 serge 814
 
579 serge 815
.ready:
233 serge 816
           xor edx, edx     ;ac_reg_0
817
           call [ctrl.codec_write16]
168 serge 818
 
233 serge 819
           xor eax, eax
820
           mov edx, CODEC_REG_POWERDOWN
821
           call [ctrl.codec_write16]
822
 
823
           mov [counter], 200     ; total 200*5 ms = 1s
168 serge 824
.wait:
579 serge 825
           mov eax, 5000   ; wait 5 ms
826
           call StallExec
827
 
233 serge 828
           mov edx, CODEC_REG_POWERDOWN
829
           call [ctrl.codec_read16]
830
           and eax, 0x0F
831
           cmp eax, 0x0F
579 serge 832
           jz .done
168 serge 833
 
233 serge 834
           sub [counter] , 1
835
           jnz .wait
168 serge 836
.err:
233 serge 837
           xor eax, eax        ; timeout error
838
           ret
579 serge 839
.done:
840
           mov eax, 2      ;force set 16-bit 2-channel PCM
841
           mov edx, GLOB_CTRL
842
           call [ctrl.ctrl_write32]
843
           mov eax, 5000   ; wait 5 ms
844
           call StallExec
845
 
233 serge 846
           call detect_codec
168 serge 847
 
233 serge 848
           xor eax, eax
849
           inc eax
850
           ret
168 serge 851
endp
852
 
853
align 4
854
proc reset_codec
227 serge 855
           mov edx, GLOB_CTRL
856
           call [ctrl.ctrl_read32]
168 serge 857
 
858
           test eax, 0x02
859
           jz .cold
860
 
861
           call warm_reset
862
           jnc .ok
863
.cold:
227 serge 864
           call cold_reset
865
           jnc .ok
168 serge 866
 
867
     if DEBUG
227 serge 868
           mov esi, msgCFail
188 serge 869
           call SysMsgBoardStr
168 serge 870
     end if
227 serge 871
           xor eax, eax     ; timeout error
872
           ret
168 serge 873
.ok:
874
           xor eax, eax
227 serge 875
           inc eax
876
           ret
168 serge 877
endp
878
 
879
align 4
880
proc warm_reset
227 serge 881
           locals
882
             counter dd ?
883
           endl
168 serge 884
 
227 serge 885
           mov eax, 0x06
886
           mov edx, GLOB_CTRL
887
           call [ctrl.ctrl_write32]
168 serge 888
 
889
     if DEBUG
227 serge 890
           mov esi, msgWarm
188 serge 891
           call SysMsgBoardStr
168 serge 892
     end if
893
 
227 serge 894
           mov [counter], 10    ; total 10*100 ms = 1s
168 serge 895
.wait:
227 serge 896
           mov eax, 100000    ; wait 100 ms
897
           call StallExec
168 serge 898
 
579 serge 899
           mov edx, CTRL_STAT
227 serge 900
           call [ctrl.ctrl_read32]
579 serge 901
           test eax, CTRL_ST_CREADY
902
           jnz .ok
903
 
904
           dec [counter]
227 serge 905
           jnz .wait
168 serge 906
 
907
     if DEBUG
227 serge 908
           mov esi, msgWRFail
188 serge 909
           call SysMsgBoardStr
168 serge 910
     end if
579 serge 911
.fail:
227 serge 912
           stc
913
           ret
168 serge 914
.ok:
915
           clc
227 serge 916
           ret
168 serge 917
endp
918
 
919
align 4
920
proc cold_reset
227 serge 921
           locals
922
             counter dd ?
923
            endl
168 serge 924
 
579 serge 925
           mov eax, 0x02
227 serge 926
           mov edx, GLOB_CTRL
927
           call [ctrl.ctrl_write32]
168 serge 928
 
929
     if DEBUG
227 serge 930
           mov esi, msgCold
188 serge 931
           call SysMsgBoardStr
168 serge 932
     end if
933
 
579 serge 934
           mov eax, 400000     ; wait 400 ms
935
           call StallExec
936
 
937
           mov [counter], 16    ; total 20*100 ms = 2s
168 serge 938
.wait:
579 serge 939
 
940
           mov edx, CTRL_STAT
941
           call [ctrl.ctrl_read32]
942
           test eax, CTRL_ST_CREADY
943
           jnz .ok
944
 
227 serge 945
           mov eax, 100000    ; wait 100 ms
946
           call StallExec
168 serge 947
 
579 serge 948
           dec [counter]
227 serge 949
           jnz .wait
168 serge 950
 
951
     if DEBUG
227 serge 952
           mov esi, msgCRFail
188 serge 953
           call SysMsgBoardStr
168 serge 954
     end if
579 serge 955
 
233 serge 956
.fail:
227 serge 957
           stc
958
           ret
168 serge 959
.ok:
579 serge 960
           mov esi, msgControl
961
           call SysMsgBoardStr
962
 
963
           mov edx, GLOB_CTRL
964
           call [ctrl.ctrl_read32]
965
           call dword2str
966
           call SysMsgBoardStr
967
 
968
           mov esi, msgStatus
969
           call SysMsgBoardStr
970
 
227 serge 971
           mov edx, CTRL_STAT
972
           call [ctrl.ctrl_read32]
579 serge 973
           push eax
974
           call dword2str
975
           call SysMsgBoardStr
976
           pop eax
977
 
978
           test eax, CTRL_ST_CREADY
168 serge 979
           jz .fail
980
           clc
227 serge 981
           ret
168 serge 982
endp
983
 
984
align 4
579 serge 985
play:
168 serge 986
           xor eax, eax
987
           mov [civ_val], eax
988
           mov edx, PCM_OUT_CIV_REG
227 serge 989
           call [ctrl.ctrl_write8]
168 serge 990
 
227 serge 991
           mov eax, 16
992
           mov [ctrl.lvi_reg], eax
993
           mov edx, PCM_OUT_LVI_REG
994
           call [ctrl.ctrl_write8]
168 serge 995
 
227 serge 996
           mov edx, PCM_OUT_CR_REG
997
           mov ax, 0x1D
998
           call [ctrl.ctrl_write8]
579 serge 999
           xor eax, eax
227 serge 1000
           ret
168 serge 1001
 
1002
align 4
579 serge 1003
stop:
227 serge 1004
           mov edx, PCM_OUT_CR_REG
1005
           mov ax, 0x0
1006
           call [ctrl.ctrl_write8]
168 serge 1007
 
227 serge 1008
           mov ax, 0x1c
1009
           mov edx, PCM_OUT_SR_REG
1010
           call [ctrl.ctrl_write16]
579 serge 1011
           xor eax, eax
227 serge 1012
           ret
168 serge 1013
 
1014
align 4
1015
proc get_dev_info stdcall, p_info:dword
1016
           virtual at esi
1017
             CTRL_INFO CTRL_INFO
1018
           end virtual
1019
 
1020
           mov esi, [p_info]
1021
           mov eax, [ctrl.int_line]
1022
           mov ebx, [ctrl.codec_io_base]
1023
           mov ecx, [ctrl.ctrl_io_base]
1024
           mov edx, [ctrl.codec_mem_base]
1025
           mov edi, [ctrl.ctrl_mem_base]
1026
 
1027
           mov [CTRL_INFO.irq], eax
1028
           mov [CTRL_INFO.codec_io_base], ebx
1029
           mov [CTRL_INFO.ctrl_io_base], ecx
1030
           mov [CTRL_INFO.codec_mem_base], edx
1031
           mov [CTRL_INFO.ctrl_mem_base], edi
1032
 
1033
           mov eax, [codec.chip_id]
1034
           mov [CTRL_INFO.codec_id], eax
1035
 
1036
           mov edx, GLOB_CTRL
1037
           call [ctrl.ctrl_read32]
1038
           mov [CTRL_INFO.glob_cntrl], eax
1039
 
1040
           mov edx, CTRL_STAT
1041
           call [ctrl.ctrl_read32]
1042
           mov [CTRL_INFO.glob_sta], eax
1043
 
1044
           mov ebx, [ctrl.pci_cmd]
1045
           mov [CTRL_INFO.pci_cmd], ebx
1046
           ret
1047
endp
1048
 
1049
align 4
1050
proc set_callback stdcall, handler:dword
227 serge 1051
           mov eax, [handler]
1052
           mov [ctrl.user_callback], eax
1053
           ret
168 serge 1054
endp
1055
 
1056
align 4
1057
proc codec_read stdcall, ac_reg:dword	   ; reg = edx, reval = eax
1058
 
227 serge 1059
           mov edx, [ac_reg]
168 serge 1060
 
227 serge 1061
           mov ebx, edx
1062
           shr ebx, 1
1063
           bt [codec.shadow_flag], ebx
1064
           jc .use_shadow
168 serge 1065
 
227 serge 1066
           call [ctrl.codec_read16]  ;change edx !!!
1067
           mov ecx, eax
168 serge 1068
 
1069
           mov edx, CTRL_STAT
227 serge 1070
           call [ctrl.ctrl_read32]
1071
           test eax, CTRL_ST_RCS
1072
           jz .read_ok
168 serge 1073
 
1074
           mov edx, CTRL_STAT
227 serge 1075
           call [ctrl.ctrl_write32]
1076
           xor eax,eax
1077
           not eax  ;timeout
1078
           ret
168 serge 1079
.read_ok:
227 serge 1080
           mov edx, [ac_reg]
1081
           mov [codec.regs+edx], cx
1082
           bts [codec.shadow_flag], ebx
1083
           mov eax, ecx
1084
           ret
168 serge 1085
.use_shadow:
227 serge 1086
           movzx eax, word [codec.regs+edx]
1087
           ret
168 serge 1088
endp
1089
 
1090
align 4
1091
proc codec_write stdcall, ac_reg:dword
227 serge 1092
           push eax
1093
           call check_semafore
1094
           and eax, eax
1095
           jz .err
1096
           pop eax
168 serge 1097
 
227 serge 1098
           mov esi, [ac_reg]
1099
           mov edx, esi
1100
           call [ctrl.codec_write16]
1101
           mov [codec.regs+esi], ax
1102
           shr esi, 1
1103
           bts [codec.shadow_flag], esi
1104
           ret
168 serge 1105
.err:
227 serge 1106
           pop eax
1107
           ret
168 serge 1108
endp
1109
 
1110
align 4
1111
proc codec_check_ready
1112
 
227 serge 1113
           mov edx, CTRL_ST
1114
           call [ctrl.ctrl_read32]
1115
           and eax, CTRL_ST_CREADY
1116
           jz .not_ready
168 serge 1117
 
227 serge 1118
           xor eax, wax
1119
           inc eax
1120
           ret
168 serge 1121
.not_ready:
227 serge 1122
           xor eax, eax
1123
           ret
168 serge 1124
endp
1125
 
1126
align 4
1127
proc check_semafore
227 serge 1128
           local counter:DWORD
168 serge 1129
 
227 serge 1130
           mov [counter], 100
168 serge 1131
.l1:
227 serge 1132
           mov edx, CTRL_CAS
1133
           call [ctrl.ctrl_read8]
1134
           and eax, CAS_FLAG
1135
           jz .ok
168 serge 1136
 
227 serge 1137
           mov eax, 1
1138
           call StallExec
1139
           sub [counter], 1
1140
           jnz .l1
1141
           xor eax, eax
1142
           ret
168 serge 1143
align 4
1144
.ok:
227 serge 1145
           xor eax,eax
1146
           inc eax
1147
           ret
168 serge 1148
endp
1149
 
1150
align 4
1151
proc StallExec
227 serge 1152
           push ecx
1153
           push edx
1154
           push ebx
1155
           push eax
168 serge 1156
 
227 serge 1157
           mov ecx, CPU_FREQ
1158
           mul ecx
1159
           mov ebx, eax       ;low
1160
           mov ecx, edx       ;high
1161
           rdtsc
1162
           add ebx, eax
233 serge 1163
           adc ecx, edx
168 serge 1164
@@:
227 serge 1165
           rdtsc
1166
           sub eax, ebx
1167
           sbb edx, ecx
233 serge 1168
           js @B
168 serge 1169
 
227 serge 1170
           pop eax
1171
           pop ebx
1172
           pop edx
1173
           pop ecx
1174
           ret
168 serge 1175
endp
1176
 
1177
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1178
;          CONTROLLER IO functions
1179
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1180
 
1181
align 4
1182
proc codec_io_r16
227 serge 1183
           add edx, [ctrl.codec_io_base]
1184
           in  ax, dx
1185
           ret
168 serge 1186
endp
1187
 
1188
align 4
1189
proc codec_io_w16
227 serge 1190
           add edx, [ctrl.codec_io_base]
1191
           out dx, ax
1192
           ret
168 serge 1193
endp
1194
 
1195
align 4
1196
proc ctrl_io_r8
227 serge 1197
           add edx, [ctrl.ctrl_io_base]
1198
           in  al, dx
1199
           ret
168 serge 1200
endp
1201
 
1202
align 4
1203
proc ctrl_io_r16
227 serge 1204
           add edx, [ctrl.ctrl_io_base]
1205
           in  ax, dx
1206
           ret
168 serge 1207
endp
1208
 
1209
align 4
1210
proc ctrl_io_r32
227 serge 1211
           add edx, [ctrl.ctrl_io_base]
1212
           in  eax, dx
1213
           ret
168 serge 1214
endp
1215
 
1216
align 4
1217
proc ctrl_io_w8
227 serge 1218
           add edx, [ctrl.ctrl_io_base]
1219
           out dx, al
1220
           ret
168 serge 1221
endp
1222
 
1223
align 4
1224
proc ctrl_io_w16
227 serge 1225
           add edx, [ctrl.ctrl_io_base]
1226
           out dx, ax
1227
           ret
168 serge 1228
endp
1229
 
1230
align 4
1231
proc ctrl_io_w32
227 serge 1232
           add edx, [ctrl.ctrl_io_base]
1233
           out dx, eax
1234
           ret
168 serge 1235
endp
1236
 
247 serge 1237
align 4
1238
dword2str:
1239
      mov  esi, hex_buff
1240
      mov ecx, -8
1241
@@:
1242
      rol eax, 4
1243
      mov ebx, eax
1244
      and ebx, 0x0F
1245
      mov bl, [ebx+hexletters]
1246
      mov [8+esi+ecx], bl
1247
      inc ecx
1248
      jnz @B
1249
      ret
1250
 
579 serge 1251
hexletters   db '0123456789ABCDEF'
1252
hex_buff     db 8 dup(0),13,10,0
247 serge 1253
 
168 serge 1254
include "codec.inc"
1255
 
188 serge 1256
align 4
168 serge 1257
devices dd (CTRL_SIS  shl 16)+VID_SIS,msg_AC, set_SIS
247 serge 1258
        dd 0
168 serge 1259
 
465 serge 1260
version      dd (5 shl 16) or (API_VERSION and 0xFFFF)
168 serge 1261
 
227 serge 1262
msg_AC       db '7012 AC97 controller',13,10, 0
1263
msg_SIS      db 'Silicon Integrated Systems',13,10, 0
1264
 
168 serge 1265
sz_sound_srv	    db 'SOUND',0
1266
 
1267
msgInit      db 'detect hardware...',13,10,0
1268
msgFail      db 'device not found',13,10,0
579 serge 1269
msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
1270
msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
168 serge 1271
msgPlay      db 'start play', 13,10,0
1272
msgStop      db 'stop play',  13,10,0
579 serge 1273
;msgNotify    db 'call notify',13,10,0
227 serge 1274
msgIRQ       db 'AC97 IRQ', 13,10,0
168 serge 1275
msgInitCtrl  db 'init controller',13,10,0
579 serge 1276
;msgInitCodec db 'init codec',13,10,0
1277
msgPrimBuff  db 'create primary buffer ...',0
1278
msgDone      db 'done',13,10,0
1279
msgRemap     db 'Remap IRQ',13,10,0
1280
;msgReg       db 'set service handler',13,10,0
168 serge 1281
msgOk        db 'service installed',13,10,0
579 serge 1282
msgCold      db 'cold reset',13,10,0
168 serge 1283
msgWarm      db 'warm reset',13,10,0
1284
msgWRFail    db 'warm reset failed',13,10,0
1285
msgCRFail    db 'cold reset failed',13,10,0
1286
msgCFail     db 'codec not ready',13,10,0
579 serge 1287
msgResetOk   db 'reset complete',13,10,0
247 serge 1288
msgStatus    db 'global status   ',0
1289
msgControl   db 'global control  ',0
579 serge 1290
msgPciCmd    db 'PCI command     ',0
1291
msgPciStat   db 'PCI status      ',0
1292
msgCtrlIsaIo db 'controller io base   ',0
1293
msgMixIsaIo  db 'codec io base        ',0
1294
msgCtrlMMIo  db 'controller mmio base ',0
1295
msgMixMMIo   db 'codec mmio base      ',0
1296
msgIrqMap    db 'AC97 irq map as      ',0
188 serge 1297
 
1298
section '.data' data readable writable align 16
1299
 
1300
pcmout_bdl       rq 32
1301
buff_list        rd 32
1302
 
1303
codec CODEC
1304
ctrl AC_CNTRL
1305
 
1306
lpc_bus  rd 1
1307
civ_val  rd 1