Subversion Repositories Kolibri OS

Rev

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