Subversion Repositories Kolibri OS

Rev

Rev 2465 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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