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