Subversion Repositories Kolibri OS

Rev

Rev 1623 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1546 Asper 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
format MS COFF
9
 
10
DEBUG		equ 1
11
 
12
include 'proc32.inc'
13
include 'imports.inc'
14
 
15
API_VERSION	equ 0x01000100
16
 
17
USE_COM_IRQ	equ 0	 ;make irq 3 and irq 4 available for PCI devices
18
IRQ_REMAP	equ 0
19
IRQ_LINE	equ 0
20
 
21
 
22
;irq 0,1,2,8,12,13 недоступны
23
;                   FEDCBA9876543210
24
VALID_IRQ	equ 1100111011111000b
25
ATTCH_IRQ	equ 0000111010100000b
26
 
27
if USE_COM_IRQ
28
ATTCH_IRQ	equ 0000111010111000b
29
end if
30
 
31
CPU_FREQ	equ  2600d
32
 
33
BIT0  EQU 0x00000001
34
BIT1  EQU 0x00000002
35
BIT5  EQU 0x00000020
36
BIT10 EQU 0x00000400
37
 
38
VID_Creative	  equ 0x1102
39
 
40
CTRL_CT0200	  equ 0x0006  ; Dell OEM version (EMU10K1X)
41
 
42
 
43
CODEC_MASTER_VOL_REG	     equ 0x02
44
CODEC_AUX_VOL		     equ 0x04 ;
45
CODEC_PCM_OUT_REG	     equ 0x18 ; PCM output volume
46
CODEC_EXT_AUDIO_REG	     equ 0x28 ; extended audio
47
CODEC_EXT_AUDIO_CTRL_REG     equ 0x2a ; extended audio control
48
CODEC_PCM_FRONT_DACRATE_REG  equ 0x2c ; PCM out sample rate
49
CODEC_PCM_SURND_DACRATE_REG  equ 0x2e ; surround sound sample rate
50
CODEC_PCM_LFE_DACRATE_REG    equ 0x30 ; LFE sample rate
51
 
52
 
53
;EMU10K1(X) host controller registers set
54
;; common offsets
55
;; some definitions were borrowed from emu10k1 driver as they seem to be the same
56
;;**********************************************************************************************;;
57
;; PCI function 0 registers, address =  + PCIBASE0                                         ;;
58
;;**********************************************************************************************;;
59
 
60
PTR			equ  0x00	     ;; Indexed register set pointer register        ;;
61
						;; NOTE: The CHANNELNUM and ADDRESS words can   ;;
62
						;; be modified independently of each other.     ;;
63
 
64
DATA			equ  0x04	     ;; Indexed register set data register           ;;
65
 
66
IPR			equ  0x08	     ;; Global interrupt pending register            ;;
67
						;; Clear pending interrupts by writing a 1 to   ;;
68
						;; the relevant bits and zero to the other bits ;;
69
IPR_MIDITRANSBUFEMPTY	equ  0x00000001      ;; MIDI UART transmit buffer empty              ;;
70
IPR_MIDIRECVBUFEMPTY	equ  0x00000002      ;; MIDI UART receive buffer empty               ;;
71
IPR_CH_0_LOOP		equ  0x00000800      ;; Channel 0 loop                               ;;
72
IPR_CH_0_HALF_LOOP	equ  0x00000100      ;; Channel 0 half loop                          ;;
73
IPR_CAP_0_LOOP		equ  0x00080000      ;; Channel capture loop                         ;;
74
IPR_CAP_0_HALF_LOOP	equ  0x00010000      ;; Channel capture half loop                    ;;
75
 
76
INTE			equ  0x0c	     ;; Interrupt enable register                    ;;
77
INTE_MIDITXENABLE	equ  0x00000001      ;; Enable MIDI transmit-buffer-empty interrupts ;;
78
INTE_MIDIRXENABLE	equ  0x00000002      ;; Enable MIDI receive-buffer-empty interrupts  ;;
79
INTE_CH_0_LOOP		equ  0x00000800      ;; Channel 0 loop                               ;;
80
INTE_CH_0_HALF_LOOP	equ  0x00000100      ;; Channel 0 half loop                          ;;
81
INTE_CAP_0_LOOP 	equ  0x00080000      ;; Channel capture loop                         ;;
82
INTE_CAP_0_HALF_LOOP	equ  0x00010000      ;; Channel capture half loop                    ;;
83
 
84
HCFG			equ  0x14	     ;; Hardware config register                     ;;
85
 
86
HCFG_LOCKSOUNDCACHE	equ  0x00000008      ;; 1 = Cancel bustmaster accesses to soundcache ;;
87
						;; NOTE: This should generally never be used.   ;;
88
HCFG_AUDIOENABLE	equ  0x00000001      ;; 0 = CODECs transmit zero-valued samples      ;;
89
						;; Should be set to 1 when the EMU10K1 is       ;;
90
						;; completely initialized.                      ;;
91
GPIO			equ  0x18	     ;; Defaults: 00001080-Analog, 00001000-SPDIF.   ;;
92
 
93
 
94
AC97DATA		equ  0x1c	     ;; AC97 register set data register (16 bit)     ;;
95
 
96
AC97ADDRESS		equ  0x1e	     ;; AC97 register set address register (8 bit)   ;;
97
 
98
;;******************************************************************************************************;;
99
;; Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers                    ;;
100
;;******************************************************************************************************;;
101
PLAYBACK_LIST_ADDR	equ  0x00	     ;; Base DMA address of a list of pointers to each period/size ;;
102
						;; One list entry: 4 bytes for DMA address,
103
						 ;; 4 bytes for period_size << 16.
104
						 ;; One list entry is 8 bytes long.
105
						 ;; One list entry for each period in the buffer.
106
						 ;;
107
PLAYBACK_LIST_SIZE	equ  0x01	     ;; Size of list in bytes << 19. E.g. 8 periods -> 0x00380000  ;;
108
PLAYBACK_LIST_PTR	equ  0x02	     ;; Pointer to the current period being played ;;
109
PLAYBACK_DMA_ADDR	equ  0x04	     ;; Playback DMA addresss ;;
110
PLAYBACK_PERIOD_SIZE	equ  0x05	     ;; Playback period size ;;
111
PLAYBACK_POINTER	equ  0x06	     ;; Playback period pointer. Sample currently in DAC ;;
112
PLAYBACK_UNKNOWN1	equ  0x07
113
PLAYBACK_UNKNOWN2	equ  0x08
114
 
115
;; Only one capture channel supported ;;
116
CAPTURE_DMA_ADDR	equ  0x10	     ;; Capture DMA address ;;
117
CAPTURE_BUFFER_SIZE	equ  0x11	     ;; Capture buffer size ;;
118
CAPTURE_POINTER 	equ  0x12	     ;; Capture buffer pointer. Sample currently in ADC ;;
119
CAPTURE_UNKNOWN 	equ  0x13
120
 
121
;; From 0x20 - 0x3f, last samples played on each channel ;;
122
 
123
TRIGGER_CHANNEL 	equ  0x40	     ;; Trigger channel playback                     ;;
124
TRIGGER_CHANNEL_0	equ  0x00000001      ;; Trigger channel 0                            ;;
125
TRIGGER_CHANNEL_1	equ  0x00000002      ;; Trigger channel 1                            ;;
126
TRIGGER_CHANNEL_2	equ  0x00000004      ;; Trigger channel 2                            ;;
127
TRIGGER_CAPTURE 	equ  0x00000100      ;; Trigger capture channel                      ;;
128
 
129
ROUTING 		equ  0x41	     ;; Setup sound routing ?                        ;;
130
ROUTING_FRONT_LEFT	equ  0x00000001
131
ROUTING_FRONT_RIGHT	equ  0x00000002
132
ROUTING_REAR_LEFT	equ  0x00000004
133
ROUTING_REAR_RIGHT	equ  0x00000008
134
ROUTING_CENTER_LFE	equ  0x00010000
135
 
136
SPCS0			equ  0x42	     ;; SPDIF output Channel Status 0 register       ;;
137
SPCS1			equ  0x43	     ;; SPDIF output Channel Status 1 register       ;;
138
SPCS2			equ  0x44	     ;; SPDIF output Channel Status 2 register       ;;
139
 
140
SPCS_CLKACCYMASK	equ  0x30000000      ;; Clock accuracy                               ;;
141
SPCS_CLKACCY_1000PPM	equ  0x00000000      ;; 1000 parts per million                       ;;
142
SPCS_CLKACCY_50PPM	equ  0x10000000      ;; 50 parts per million                         ;;
143
SPCS_CLKACCY_VARIABLE	equ  0x20000000      ;; Variable accuracy                            ;;
144
SPCS_SAMPLERATEMASK	equ  0x0f000000      ;; Sample rate                                  ;;
145
SPCS_SAMPLERATE_44	equ  0x00000000      ;; 44.1kHz sample rate                          ;;
146
SPCS_SAMPLERATE_48	equ  0x02000000      ;; 48kHz sample rate                            ;;
147
SPCS_SAMPLERATE_32	equ  0x03000000      ;; 32kHz sample rate                            ;;
148
SPCS_CHANNELNUMMASK	equ  0x00f00000      ;; Channel number                               ;;
149
SPCS_CHANNELNUM_UNSPEC	equ  0x00000000      ;; Unspecified channel number                   ;;
150
SPCS_CHANNELNUM_LEFT	equ  0x00100000      ;; Left channel                                 ;;
151
SPCS_CHANNELNUM_RIGHT	equ  0x00200000      ;; Right channel                                ;;
152
SPCS_SOURCENUMMASK	equ  0x000f0000      ;; Source number                                ;;
153
SPCS_SOURCENUM_UNSPEC	equ  0x00000000      ;; Unspecified source number                    ;;
154
SPCS_GENERATIONSTATUS	equ  0x00008000      ;; Originality flag (see IEC-958 spec)          ;;
155
SPCS_CATEGORYCODEMASK	equ  0x00007f00      ;; Category code (see IEC-958 spec)             ;;
156
SPCS_MODEMASK		equ  0x000000c0      ;; Mode (see IEC-958 spec)                      ;;
157
SPCS_EMPHASISMASK	equ  0x00000038      ;; Emphasis                                     ;;
158
SPCS_EMPHASIS_NONE	equ  0x00000000      ;; No emphasis                                  ;;
159
SPCS_EMPHASIS_50_15	equ  0x00000008      ;; 50/15 usec 2 channel                         ;;
160
SPCS_COPYRIGHT		equ  0x00000004      ;; Copyright asserted flag -- do not modify     ;;
161
SPCS_NOTAUDIODATA	equ  0x00000002      ;; 0 = Digital audio, 1 = not audio             ;;
162
SPCS_PROFESSIONAL	equ  0x00000001      ;; 0 = Consumer (IEC-958), 1 = pro (AES3-1992)  ;;
163
 
164
SPDIF_SELECT		equ  0x45	     ;; Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF ;;
165
 
166
;; This is the MPU port on the card                                                             ;;
167
MUDATA		equ  0x47
168
MUCMD		equ  0x48
169
MUSTAT		equ  MUCMD
170
 
171
;; From 0x50 - 0x5f, last samples captured ;;
172
 
173
 
174
SRV_GETVERSION	      equ  0
175
DEV_PLAY	      equ  1
176
DEV_STOP	      equ  2
177
DEV_CALLBACK	      equ  3
178
DEV_SET_BUFF	      equ  4
179
DEV_NOTIFY	      equ  5
180
DEV_SET_MASTERVOL     equ  6
181
DEV_GET_MASTERVOL     equ  7
182
DEV_GET_INFO	      equ  8
183
 
184
struc AC_CNTRL		    ;AC controller base class
185
{ .bus		      dd ?
186
  .devfn	      dd ?
187
 
188
  .vendor	      dd ?
189
  .dev_id	      dd ?
190
  .pci_cmd	      dd ?
191
  .pci_stat	      dd ?
192
 
193
  .codec_io_base      dd ?
194
  .codec_mem_base     dd ?
195
 
196
  .ctrl_io_base       dd ?
197
  .ctrl_mem_base      dd ?
198
  .cfg_reg	      dd ?
199
  .int_line	      dd ?
200
 
201
  .vendor_ids	      dd ?    ;vendor id string
202
  .ctrl_ids	      dd ?    ;hub id string
203
 
204
  .buffer	      dd ?
205
 
206
  .notify_pos	      dd ?
207
  .notify_task	      dd ?
208
 
209
  .lvi_reg	      dd ?
210
  .ctrl_setup	      dd ?
211
  .user_callback      dd ?
212
  .codec_read16       dd ?
213
  .codec_write16      dd ?
214
 
215
  .ctrl_read8	      dd ?
216
  .ctrl_read16	      dd ?
217
  .ctrl_read32	      dd ?
218
 
219
  .ctrl_write8	      dd ?
220
  .ctrl_write16       dd ?
221
  .ctrl_write32       dd ?
222
}
223
 
224
struc CODEC		   ;Audio Chip base class
225
{
226
  .chip_id	      dd ?
227
  .flags	      dd ?
228
  .status	      dd ?
229
 
230
  .ac_vendor_ids      dd ?    ;ac vendor id string
231
  .chip_ids	      dd ?    ;chip model string
232
 
233
  .shadow_flag	      dd ?
234
		      dd ?
235
 
236
  .regs 	      dw ?     ; codec registers
237
  .reg_master_vol     dw ?     ;0x02
238
  .reg_aux_out_vol    dw ?     ;0x04
239
  .reg_mone_vol       dw ?     ;0x06
240
  .reg_master_tone    dw ?     ;0x08
241
  .reg_beep_vol       dw ?     ;0x0A
242
  .reg_phone_vol      dw ?     ;0x0C
243
  .reg_mic_vol	      dw ?     ;0x0E
244
  .reg_line_in_vol    dw ?     ;0x10
245
  .reg_cd_vol	      dw ?     ;0x12
246
  .reg_video_vol      dw ?     ;0x14
247
  .reg_aux_in_vol     dw ?     ;0x16
248
  .reg_pcm_out_vol    dw ?     ;0x18
249
  .reg_rec_select     dw ?     ;0x1A
250
  .reg_rec_gain       dw ?     ;0x1C
251
  .reg_rec_gain_mic   dw ?     ;0x1E
252
  .reg_gen	      dw ?     ;0x20
253
  .reg_3d_ctrl	      dw ?     ;0X22
254
  .reg_page	      dw ?     ;0X24
255
  .reg_powerdown      dw ?     ;0x26
256
  .reg_ext_audio      dw ?     ;0x28
257
  .reg_ext_st	      dw ?     ;0x2a
258
  .reg_pcm_front_rate dw ?     ;0x2c
259
  .reg_pcm_surr_rate  dw ?     ;0x2e
260
  .reg_lfe_rate       dw ?     ;0x30
261
  .reg_pcm_in_rate    dw ?     ;0x32
262
		      dw ?     ;0x34
263
  .reg_cent_lfe_vol   dw ?     ;0x36
264
  .reg_surr_vol       dw ?     ;0x38
265
  .reg_spdif_ctrl     dw ?     ;0x3A
266
		      dw ?     ;0x3C
267
		      dw ?     ;0x3E
268
		      dw ?     ;0x40
269
		      dw ?     ;0x42
270
		      dw ?     ;0x44
271
		      dw ?     ;0x46
272
		      dw ?     ;0x48
273
		      dw ?     ;0x4A
274
		      dw ?     ;0x4C
275
		      dw ?     ;0x4E
276
		      dw ?     ;0x50
277
		      dw ?     ;0x52
278
		      dw ?     ;0x54
279
		      dw ?     ;0x56
280
		      dw ?     ;0x58
281
		      dw ?     ;0x5A
282
		      dw ?     ;0x5C
283
		      dw ?     ;0x5E
284
  .reg_page_0	      dw ?     ;0x60
285
  .reg_page_1	      dw ?     ;0x62
286
  .reg_page_2	      dw ?     ;0x64
287
  .reg_page_3	      dw ?     ;0x66
288
  .reg_page_4	      dw ?     ;0x68
289
  .reg_page_5	      dw ?     ;0x6A
290
  .reg_page_6	      dw ?     ;0x6C
291
  .reg_page_7	      dw ?     ;0x6E
292
		      dw ?     ;0x70
293
		      dw ?     ;0x72
294
		      dw ?     ;0x74
295
		      dw ?     ;0x76
296
		      dw ?     ;0x78
297
		      dw ?     ;0x7A
298
  .reg_vendor_id_1    dw ?     ;0x7C
299
  .reg_vendor_id_2    dw ?     ;0x7E
300
 
301
 
302
  .reset	      dd ?    ;virual
303
  .set_master_vol     dd ?
304
}
305
 
306
struc CTRL_INFO
307
{   .pci_cmd	      dd ?
308
    .irq	      dd ?
309
    .glob_cntrl       dd ?
310
    .glob_sta	      dd ?
311
    .codec_io_base    dd ?
312
    .ctrl_io_base     dd ?
313
    .codec_mem_base   dd ?
314
    .ctrl_mem_base    dd ?
315
    .codec_id	      dd ?
316
}
317
 
318
struc IOCTL
319
{  .handle	      dd ?
320
   .io_code	      dd ?
321
   .input	      dd ?
322
   .inp_size	      dd ?
323
   .output	      dd ?
324
   .out_size	      dd ?
325
}
326
 
327
virtual at 0
328
  IOCTL IOCTL
329
end virtual
330
 
331
EVENT_NOTIFY	equ 0x00000200
332
 
333
public START
334
public service_proc
335
public version
336
 
337
section '.flat' code readable align 16
338
 
339
proc START stdcall, state:dword
340
 
341
	   cmp	 [state], 1
342
	   jne	 .stop
343
 
344
     if DEBUG
345
	   mov	 esi, msgInit
346
	   call  SysMsgBoardStr
347
     end if
348
 
349
	   call     detect_controller
350
	   test     eax, eax
351
	   jz	    .fail
352
 
353
     if DEBUG
354
	   mov	 esi,[ctrl.vendor_ids]
355
	   call  SysMsgBoardStr
356
	   mov	 esi, [ctrl.ctrl_ids]
357
	   call  SysMsgBoardStr
358
     end if
359
 
360
	   call     init_controller
361
	   test     eax, eax
362
	   jz	    .fail
363
 
364
	   call     init_codec
365
	   test     eax, eax
366
	   jz	    .fail
367
 
368
	   call     setup_codec
369
 
370
	   mov	    esi, msgPrimBuff
371
	   call     SysMsgBoardStr
372
	   call     create_primary_buff
373
	   mov	    esi, msgDone
374
	   call     SysMsgBoardStr
375
 
376
  if IRQ_REMAP
377
	   pushf
378
	   cli
379
 
380
	   mov	    ebx, [ctrl.int_line]
381
	   in	    al, 0xA1
382
	   mov	    ah, al
383
	   in	    al, 0x21
384
	   test     ebx, ebx
385
	   jz	    .skip
386
	   bts	    ax, bx			;mask old line
387
.skip:
388
	   bts	    ax, IRQ_LINE		;mask new ine
389
	   out	    0x21, al
390
	   mov	    al, ah
391
	   out	    0xA1, al
392
 
393
	   stdcall  PciWrite8, 0, 0xF8, 0x61, IRQ_LINE	;remap IRQ
394
 
395
	   mov	    dx, 0x4d0			;8259 ELCR1
396
	   in	    al, dx
397
	   bts	    ax, IRQ_LINE
398
	   out	    dx, al			;set level-triggered mode
399
	   mov	    [ctrl.int_line], IRQ_LINE
400
	   popf
401
	   mov	    esi, msgRemap
402
	   call     SysMsgBoardStr
403
  end if
404
 
405
	   mov	    eax, VALID_IRQ
406
	   mov	    ebx, [ctrl.int_line]
407
	   mov	    esi, msgInvIRQ
408
	   bt	    eax, ebx
409
	   jnc	    .fail_msg
410
	   mov	    eax, ATTCH_IRQ
411
	   mov	    esi, msgAttchIRQ
412
	   bt	    eax, ebx
413
	   jnc	    .fail_msg
414
 
415
	   stdcall  AttachIntHandler, ebx, ac97_irq, dword 0
416
	   stdcall  create
417
 
418
.reg:
419
	   stdcall  RegService, sz_sound_srv, service_proc
420
	   ret
421
.fail:
422
     if DEBUG
423
	   mov	 esi, msgFail
424
	   call  SysMsgBoardStr
425
     end if
426
	   xor	    eax, eax
427
	   ret
428
.fail_msg:
429
	   call     SysMsgBoardStr
430
	   xor	    eax, eax
431
	   ret
432
.stop:
433
	   call     stop
434
	   xor	    eax, eax
435
	   ret
436
endp
437
 
438
handle	   equ	IOCTL.handle
439
io_code    equ	IOCTL.io_code
440
input	   equ	IOCTL.input
441
inp_size   equ	IOCTL.inp_size
442
output	   equ	IOCTL.output
443
out_size   equ	IOCTL.out_size
444
 
445
align 4
446
proc service_proc stdcall, ioctl:dword
447
 
448
	   mov	    edi, [ioctl]
449
	   mov	    eax, [edi+io_code]
450
 
451
	   cmp	    eax, SRV_GETVERSION
452
	   jne	    @F
453
	   mov	    eax, [edi+output]
454
	   cmp	    [edi+out_size], 4
455
	   jne	    .fail
456
 
457
	   mov	    [eax], dword API_VERSION
458
	   xor	    eax, eax
459
	   ret
460
@@:
461
	   cmp	    eax, DEV_PLAY
462
	   jne	    @F
463
     if DEBUG
464
	   mov	esi, msgPlay
465
	   call SysMsgBoardStr
466
     end if
467
	   call     play
468
	   ret
469
@@:
470
	   cmp	    eax, DEV_STOP
471
	   jne	    @F
472
     if DEBUG
473
	   mov	esi, msgStop
474
	   call SysMsgBoardStr
475
     end if
476
	   call     stop
477
	   ret
478
@@:
479
	   cmp	    eax, DEV_CALLBACK
480
	   jne	    @F
481
	   mov	    ebx, [edi+input]
482
	   stdcall  set_callback, [ebx]
483
	   ret
484
@@:
485
	   cmp	    eax, DEV_SET_MASTERVOL
486
	   jne	    @F
487
	   mov	    eax, [edi+input]
488
	   mov	    eax, [eax]
489
	   call     set_master_vol	;eax= vol
490
	   ret
491
@@:
492
	   cmp	    eax, DEV_GET_MASTERVOL
493
	   jne	    @F
494
	   mov	    ebx, [edi+output]
495
	   stdcall  get_master_vol, ebx
496
	   ret
497
@@:
498
	   cmp	    eax, DEV_GET_INFO
499
	   jne	    @F
500
	   mov	    ebx, [edi+output]
501
	   stdcall  get_dev_info, ebx
502
	   ret
503
@@:
504
.fail:
505
	   or	    eax, -1
506
	   ret
507
endp
508
 
509
restore   handle
510
restore   io_code
511
restore   input
512
restore   inp_size
513
restore   output
514
restore   out_size
515
 
516
 
517
align 4
518
proc ac97_irq
519
	   locals
520
	     status dd 0
521
	   endl
522
 
523
;        status = inl(chip->port + IPR);
524
	   mov	    edx, IPR
525
	   call     [ctrl.ctrl_read32]
526
	   test     eax, eax
527
	   jz	    @f
528
 
529
	   mov	    dword [status], eax
530
 
531
	   mov	    ebx, dword [buff_list]
532
	   cmp	    [ctrl.user_callback], 0
533
	   je	    @f
534
	   stdcall  [ctrl.user_callback], ebx
535
       @@:
536
	   mov	    eax, dword [status] 	  ;; ack ;;
537
	   mov	    edx, IPR
538
	   call     [ctrl.ctrl_write32]
539
	   ret
540
endp
541
 
542
 
543
align 4
544
proc create_primary_buff
545
 
546
	   stdcall  KernelAlloc, 0x10000
547
	   mov	    [ctrl.buffer], eax
548
 
549
	   mov	    edi, eax
550
	   mov	    ecx, 0x10000/4
551
	   xor	    eax, eax
552
	   cld
553
	   rep	    stosd
554
 
555
	   mov	    eax, [ctrl.buffer]
556
	   call     GetPgAddr
557
 
558
	   mov edi, pcmout_bdl
559
	   stosd
560
	   mov	    eax, 0x4000000
561
	   stosd
562
 
563
	   mov	    edi, buff_list
564
	   mov	    eax, [ctrl.buffer]
565
	   stosd		     ;1.]
566
 
567
	   mov	    eax, [ctrl.buffer]
568
	   call     GetPgAddr
569
 
570
	   stdcall  ptr_write, PLAYBACK_POINTER,   0, 0
571
	   stdcall  ptr_write, PLAYBACK_UNKNOWN1,  0, 0
572
	   stdcall  ptr_write, PLAYBACK_UNKNOWN2,  0, 0
573
	   stdcall  ptr_write, PLAYBACK_DMA_ADDR,  0, eax
574
 
575
	   mov	    eax, pcmout_bdl
576
	   mov	    ebx, eax
577
	   call     GetPgAddr
578
	   and	    ebx, 0xFFF
579
	   add	    eax, ebx
580
 
581
	   stdcall  ptr_write, PLAYBACK_LIST_ADDR, 0, eax
582
	   stdcall  ptr_write, PLAYBACK_LIST_SIZE, 0, 0
583
	   stdcall  ptr_write, PLAYBACK_LIST_PTR,  0, 0
584
 
585
	   ;mov     eax, 0x00004000
586
	   ;shl     eax, 16
587
	   stdcall  ptr_write, PLAYBACK_PERIOD_SIZE, 0, 0x40000000;eax
588
 
589
	   ret
590
endp
591
 
592
 
593
align 4
594
proc detect_controller
595
	   locals
596
	     last_bus dd ?
597
	     bus      dd ?
598
	     devfn    dd ?
599
	   endl
600
 
601
	   xor eax, eax
602
	   mov [bus], eax
603
	   inc eax
604
	   call PciApi
605
	   cmp eax, -1
606
	   je .err
607
 
608
	   mov [last_bus], eax
609
 
610
.next_bus:
611
	   and [devfn], 0
612
.next_dev:
613
	   stdcall PciRead32, [bus], [devfn], dword 0
614
	   test eax, eax
615
	   jz .next
616
	   cmp eax, -1
617
	   je .next
618
 
619
	   mov edi, devices
620
@@:
621
	   mov ebx, [edi]
622
	   test ebx, ebx
623
	   jz .next
624
 
625
	   cmp eax, ebx
626
	   je .found
627
	   add edi, 12
628
	   jmp @B
629
.next:
630
	   inc [devfn]
631
	   cmp [devfn], 256
632
	   jb .next_dev
633
	   mov eax, [bus]
634
	   inc eax
635
	   mov [bus], eax
636
	   cmp eax, [last_bus]
637
	   jna .next_bus
638
	   xor eax, eax
639
	   ret
640
.found:
641
	   mov ebx, [bus]
642
	   mov [ctrl.bus], ebx
643
 
644
	   mov ecx, [devfn]
645
	   mov [ctrl.devfn], ecx
646
 
647
	   mov edx, eax
648
	   and edx, 0xFFFF
649
	   mov [ctrl.vendor], edx
650
	   shr eax, 16
651
	   mov [ctrl.dev_id], eax
652
 
653
	   mov ebx, [edi+4]
654
	   mov [ctrl.ctrl_ids], ebx
655
	   mov esi, [edi+8]
656
	   mov [ctrl.ctrl_setup], esi
657
 
658
	   cmp edx, VID_Creative
659
	   jne @F
660
	   mov [ctrl.vendor_ids], msg_Creative
661
	   ret
662
@@:
663
 
664
.err:
665
	   xor eax, eax
666
	   mov [ctrl.vendor_ids], eax	  ;something  wrong ?
667
	   ret
668
endp
669
 
670
align 4
671
proc init_controller
672
 
673
	   stdcall  PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x2C
674
	   mov	    esi, msgPciSubsys
675
	   call     SysMsgBoardStr
676
	   call     dword2str
677
	   call     SysMsgBoardStr
678
 
679
	   stdcall  PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
680
	   mov	    ebx, eax
681
	   and	    eax, 0xFFFF
682
	   mov	    [ctrl.pci_cmd], eax
683
	   shr	    ebx, 16
684
	   mov	    [ctrl.pci_stat], ebx
685
 
686
	   mov	    esi, msgPciCmd
687
	   call     SysMsgBoardStr
688
	   call     dword2str
689
	   call     SysMsgBoardStr
690
 
691
	   mov	    esi, msgPciStat
692
	   call     SysMsgBoardStr
693
	   mov	    eax, [ctrl.pci_stat]
694
	   call     dword2str
695
	   call     SysMsgBoardStr
696
 
697
	   mov	    esi, msgCtrlIsaIo
698
	   call     SysMsgBoardStr
699
	   stdcall  PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
700
	   call     dword2str
701
	   call     SysMsgBoardStr
702
 
703
	   and	    eax, 0xFFC0
704
	   mov	    [ctrl.ctrl_io_base], eax
705
 
706
.default:
707
	   stdcall  PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
708
	   and	    eax, 0xFF
709
@@:
710
	   mov	    [ctrl.int_line], eax
711
 
712
	   call     [ctrl.ctrl_setup]
713
	   xor	    eax, eax
714
	   inc	    eax
715
	   ret
716
endp
717
 
718
align 4
719
proc set_Creative
720
	   mov	    [ctrl.codec_read16],  codec_io_r16	  ;virtual
721
	   mov	    [ctrl.codec_write16], codec_io_w16	  ;virtual
722
 
723
	   mov	    [ctrl.ctrl_read8 ],  ctrl_io_r8	  ;virtual
724
	   mov	    [ctrl.ctrl_read16],  ctrl_io_r16	  ;virtual
725
	   mov	    [ctrl.ctrl_read32],  ctrl_io_r32	  ;virtual
726
 
727
	   mov	    [ctrl.ctrl_write8 ], ctrl_io_w8	  ;virtual
728
	   mov	    [ctrl.ctrl_write16], ctrl_io_w16	  ;virtual
729
	   mov	    [ctrl.ctrl_write32], ctrl_io_w32	  ;virtual
730
	   ret
731
endp
732
 
733
 
734
align 4
735
proc init_codec
736
	   call     reset_codec
737
	   test     eax, eax
738
	   jz	    .err
739
	   call     detect_codec
740
	   xor	    eax, eax
741
	   inc	    eax
742
	   ret
743
     .err:
744
	   xor	    eax, eax
745
	   ret
746
endp
747
 
748
align 4
749
proc reset_codec
750
	   locals
751
	     counter dd ?
752
	   endl
753
 
754
     if DEBUG
755
	   mov	 esi, msgCold
756
	   call  SysMsgBoardStr
757
     end if
758
 
759
	   mov	    eax, 100000     ; wait 100 ms ;400000     ; wait 400 ms
760
	   call     StallExec
761
 
762
	   stdcall  ptr_read, TRIGGER_CHANNEL, 0
763
 
764
	   mov	    [counter], 16    ; total 20*100 ms = 2s
765
.wait:
766
	   stdcall  codec_read, dword 0x26
767
	   test     eax, 1
768
	   jnz	    .ok
769
 
770
	   mov	    eax, 100000    ; wait 100 ms
771
	   call     StallExec
772
 
773
	   dec	    [counter]
774
	   jnz	    .wait
775
 
776
     if DEBUG
777
	   mov	 esi, msgCRFail
778
	   call  SysMsgBoardStr
779
     end if
780
 
781
.fail:
782
	   stc
783
	   ret
784
.ok:
785
 
786
 
787
	   xor	    eax, eax
788
	   inc	    eax
789
	   ret
790
endp
791
 
792
 
793
align 4
794
play:
795
	   mov	    eax, INTE_CH_0_LOOP
796
	   stdcall  intr_enable, eax
797
 
798
	   stdcall  ptr_read, TRIGGER_CHANNEL, 0
799
	   mov	    ebx, TRIGGER_CHANNEL_0
800
	   or	    eax, ebx
801
	   stdcall  ptr_write, TRIGGER_CHANNEL, 0, eax
802
 
803
	   xor	    eax, eax
804
	   ret
805
 
806
align 4
807
stop:
808
	   mov	    eax, INTE_CH_0_LOOP or INTE_CH_0_HALF_LOOP
809
	   stdcall  intr_disable, eax
810
 
811
	   stdcall  ptr_read, TRIGGER_CHANNEL, 0
812
	   mov	    ebx, TRIGGER_CHANNEL_0
813
	   xor	    ebx, -1
814
	   or	    eax, ebx
815
	   stdcall  ptr_write, TRIGGER_CHANNEL, 0, eax
816
	   xor	    eax, eax
817
	   ret
818
 
819
align 4
820
proc get_dev_info stdcall, p_info:dword
821
	   virtual at esi
822
	     CTRL_INFO CTRL_INFO
823
	   end virtual
824
 
825
	   mov	    esi, [p_info]
826
	   mov	    eax, [ctrl.int_line]
827
	   mov	    ecx, [ctrl.ctrl_io_base]
828
	   mov	    [CTRL_INFO.irq], eax
829
	   mov	    [CTRL_INFO.ctrl_io_base], ecx
830
	   mov	    eax, [codec.chip_id]
831
	   mov	    [CTRL_INFO.codec_id], eax
832
	   mov	    ebx, [ctrl.pci_cmd]
833
	   mov	    [CTRL_INFO.pci_cmd], ebx
834
 
835
	   xor	    eax, eax
836
	   mov	    [CTRL_INFO.codec_io_base], eax
837
	   mov	    [CTRL_INFO.codec_mem_base], eax
838
	   mov	    [CTRL_INFO.ctrl_mem_base], eax
839
	   mov	    [CTRL_INFO.glob_cntrl], eax
840
	   mov	    [CTRL_INFO.glob_sta], eax
841
	   ret
842
endp
843
 
844
align 4
845
proc set_callback stdcall, handler:dword
846
	   mov	    eax, [handler]
847
	   mov	    [ctrl.user_callback], eax
848
	   ret
849
endp
850
 
851
 
852
align 4
853
proc create stdcall
854
	   stdcall  PciRead16, [ctrl.bus], [ctrl.devfn], dword 4
855
	   test     eax, 4 ; test master bit
856
	   jnz	    @f
857
	   or	    eax, 4
858
	   stdcall  PciWrite16, [ctrl.bus], [ctrl.devfn], dword 4, eax ; set master bit
859
	 @@:
860
 
861
	   xor	    eax, eax
862
	   mov	    edx, INTE
863
	   call     [ctrl.ctrl_write32]
864
 
865
	   stdcall  ptr_write, SPCS0, 0, \
866
			       SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
867
			       SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
868
			       SPCS_GENERATIONSTATUS or 0x00001200 or \
869
			       0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
870
	   stdcall  ptr_write, SPCS1, 0, \
871
			       SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
872
			       SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
873
			       SPCS_GENERATIONSTATUS or 0x00001200 or \
874
			       0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
875
	   stdcall  ptr_write, SPCS2, 0, \
876
			       SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
877
			       SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
878
			       SPCS_GENERATIONSTATUS or 0x00001200 or \
879
			       0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
880
 
881
	   stdcall  ptr_write, SPDIF_SELECT, 0, 0x700  ; disable SPDIF
882
	   stdcall  ptr_write, ROUTING, 0, 0x1003F     ; routing
883
	   stdcall  gpio_write, 0x1080		       ; analog mode
884
 
885
	   mov	    eax, dword HCFG_LOCKSOUNDCACHE or HCFG_AUDIOENABLE
886
	   mov	    edx, HCFG
887
	   call     [ctrl.ctrl_write32]
888
	   ret
889
endp
890
 
891
align 4
892
proc codec_read stdcall, reg:dword
893
	   stdcall  ac97_read, dword [reg]
894
	   ret
895
endp
896
 
897
 
898
align 4
899
proc codec_write stdcall, reg:dword
900
	   stdcall  ac97_write, dword [reg], eax
901
	   ret
902
endp
903
 
904
 
905
align 4
906
proc ac97_read stdcall, reg:dword
907
	   push     edx
908
	   mov	    eax, dword [reg]
909
	   mov	    edx, AC97ADDRESS
910
	   call     [ctrl.ctrl_write8]
911
 
912
	   mov	    edx, AC97DATA
913
	   call     [ctrl.ctrl_read16]
914
	   and	    eax, 0xFFFF
915
	   pop	    edx
916
	   ret
917
endp
918
 
919
align 4
920
proc ac97_write stdcall, reg:dword, val:dword
921
	   push     eax edx
922
	   mov	    eax, dword [reg]
923
	   mov	    edx, AC97ADDRESS
924
	   call     [ctrl.ctrl_write8]
925
 
926
	   mov	    eax, dword [val]
927
	   mov	    edx, AC97DATA
928
	   call     [ctrl.ctrl_write16]
929
	   pop	    edx eax
930
	   ret
931
endp
932
 
933
align 4
934
proc ptr_read stdcall, reg:dword, chn:dword
935
	   push     edx
936
	   mov	    eax, dword [reg]
937
	   shl	    eax, 16
938
	   or	    eax, dword [chn]
939
 
940
	   mov	    edx, PTR
941
	   call     [ctrl.ctrl_write32]
942
 
943
	   mov	    edx, DATA
944
	   call     [ctrl.ctrl_read32]
945
	   pop	    edx
946
	ret
947
endp
948
 
949
align 4
950
proc ptr_write stdcall, reg:dword, chn:dword, data:dword
951
	   push     eax edx
952
	   mov	    eax, dword [reg]
953
	   shl	    eax, 16
954
	   or	    eax, dword [chn]
955
 
956
	   mov	    edx, PTR
957
	   call     [ctrl.ctrl_write32]
958
 
959
	   mov	    eax, dword [data]
960
	   mov	    edx, DATA
961
	   call     [ctrl.ctrl_write32]
962
	   pop	    edx eax
963
	ret
964
endp
965
 
966
align 4
967
proc intr_enable stdcall, intrenb:dword
968
	   push     edx
969
	   mov	    edx, INTE
970
	   call     [ctrl.ctrl_read32]
971
 
972
	   or	    eax, dword [intrenb]
973
	   mov	    edx, INTE
974
	   call     [ctrl.ctrl_write32]
975
	   pop	    edx
976
	   ret
977
endp
978
 
979
align 4
980
proc intr_disable stdcall, intrenb:dword
981
	   push     eax ebx edx
982
	   mov	    edx, INTE
983
	   call     [ctrl.ctrl_read32]
984
 
985
	   mov	    ebx, dword [intrenb]
986
	   xor	    ebx, -1
987
	   and	    eax, ebx
988
	   mov	    edx, INTE
989
	   call     [ctrl.ctrl_write32]
990
	   pop	    edx ebx eax
991
	   ret
992
endp
993
 
994
align 4
995
proc gpio_write stdcall, value:dword
996
	   push     eax edx
997
	   mov	    eax, dword [value]
998
	   mov	    edx, GPIO
999
	   call     [ctrl.ctrl_write32]
1000
	   pop	    edx eax
1001
	   ret
1002
endp
1003
 
1004
 
1005
align 4
1006
proc StallExec
1007
	   push     ecx
1008
	   push     edx
1009
	   push     ebx
1010
	   push     eax
1011
 
1012
	   mov	    ecx, CPU_FREQ
1013
	   mul	    ecx
1014
	   mov	    ebx, eax	   ;low
1015
	   mov	    ecx, edx	   ;high
1016
	   rdtsc
1017
	   add	    ebx, eax
1018
	   adc	    ecx, edx
1019
@@:
1020
	   rdtsc
1021
	   sub	    eax, ebx
1022
	   sbb	    edx, ecx
1023
	   js	    @B
1024
 
1025
	   pop	    eax
1026
	   pop	    ebx
1027
	   pop	    edx
1028
	   pop	    ecx
1029
	   ret
1030
endp
1031
 
1032
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1033
;          CONTROLLER IO functions
1034
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1035
 
1036
align 4
1037
proc codec_io_r16 ;Not used.
1038
	   ;mov      edx, [ctrl.ctrl_io_base]
1039
	   ;in       eax, dx
1040
	   ret
1041
endp
1042
 
1043
align 4
1044
proc codec_io_w16 ;Not used.
1045
	   ;mov      edx, [ctrl.ctrl_io_base]
1046
	   ;out      dx,  eax
1047
	   ret
1048
endp
1049
 
1050
align 4
1051
proc ctrl_io_r8
1052
	   add	    edx, [ctrl.ctrl_io_base]
1053
	   in	    al, dx
1054
	   ret
1055
endp
1056
 
1057
align 4
1058
proc ctrl_io_r16
1059
	   add	    edx, [ctrl.ctrl_io_base]
1060
	   in	    ax, dx
1061
	   ret
1062
endp
1063
 
1064
align 4
1065
proc ctrl_io_r32
1066
	   add	    edx, [ctrl.ctrl_io_base]
1067
	   in	    eax, dx
1068
	   ret
1069
endp
1070
 
1071
align 4
1072
proc ctrl_io_w8
1073
	   add	    edx, [ctrl.ctrl_io_base]
1074
	   out	    dx, al
1075
	   ret
1076
endp
1077
 
1078
align 4
1079
proc ctrl_io_w16
1080
	   add	    edx, [ctrl.ctrl_io_base]
1081
	   out	    dx, ax
1082
	   ret
1083
endp
1084
 
1085
align 4
1086
proc ctrl_io_w32
1087
	   add	    edx, [ctrl.ctrl_io_base]
1088
	   out	    dx, eax
1089
	   ret
1090
endp
1091
 
1092
 
1093
align 4
1094
dword2str:
1095
	   push     eax ebx ecx
1096
	   mov	    esi, hex_buff
1097
	   mov	    ecx, -8
1098
   @@:
1099
	   rol	    eax, 4
1100
	   mov	    ebx, eax
1101
	   and	    ebx, 0x0F
1102
	   mov	    bl, [ebx+hexletters]
1103
	   mov	    [8+esi+ecx], bl
1104
	   inc	    ecx
1105
	   jnz	    @B
1106
	   pop	    ecx ebx eax
1107
	   ret
1108
 
1109
hexletters   db '0123456789ABCDEF'
1110
hex_buff     db 8 dup(0),13,10,0
1111
 
1112
 
1113
include "codec.inc"
1114
 
1115
align 4
1116
devices dd (CTRL_CT0200 shl 16)+VID_Creative,msg_CT_EMU10K1X,set_Creative
1117
	dd 0	;terminator
1118
 
1119
 
1120
version      dd (5 shl 16) or (API_VERSION and 0xFFFF)
1121
 
1122
msg_CT_EMU10K1X  db 'SB Live! Dell OEM', 13,10, 0
1123
msg_Creative	 db 'Creative ', 0
1124
 
1125
szKernel	    db 'KERNEL', 0
1126
sz_sound_srv	    db 'SOUND',0
1127
 
1128
msgInit      db 'detect hardware...',13,10,0
1129
msgFail      db 'device not found',13,10,0
1130
msgAttchIRQ  db 'IRQ line not supported', 13,10, 0
1131
msgInvIRQ    db 'IRQ line not assigned or invalid', 13,10, 0
1132
msgPlay      db 'start play', 13,10,0
1133
msgStop      db 'stop play',  13,10,0
1134
msgIRQ	     db 'AC97 IRQ', 13,10,0
1135
;msgInitCtrl  db 'init controller',13,10,0
1136
;msgInitCodec db 'init codec',13,10,0
1137
msgPrimBuff  db 'create primary buffer ...',0
1138
msgDone      db 'done',13,10,0
1139
msgRemap     db 'Remap IRQ',13,10,0
1140
;msgReg       db 'set service handler',13,10,0
1141
;msgOk        db 'service installed',13,10,0
1142
msgCold      db 'cold reset',13,10,0
1143
;msgWarm      db 'warm reset',13,10,0
1144
;msgWRFail    db 'warm reset failed',13,10,0
1145
msgCRFail    db 'cold reset failed',13,10,0
1146
;msgCFail     db 'codec not ready',13,10,0
1147
;msgCInvalid  db 'codec is not valid',13,10,0 ;Asper
1148
;msgResetOk   db 'reset complete',13,10,0
1149
;msgStatus    db 'global status   ',0
1150
;msgControl   db 'global control  ',0
1151
msgPciCmd    db 'PCI command     ',0
1152
msgPciStat   db 'PCI status      ',0
1153
msgPciSubsys db 'PCI subsystem   ',0
1154
msgCtrlIsaIo db 'controller io base   ',0
1155
;msgMixIsaIo  db 'codec io base        ',0
1156
;msgCtrlMMIo  db 'controller mmio base ',0
1157
;msgMixMMIo   db 'codec mmio base      ',0
1158
;msgIrqMap    db 'AC97 irq map as      ',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