Subversion Repositories Kolibri OS

Rev

Rev 5363 | Details | Compare with Previous | Last modification | View Log | RSS feed

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