Fasm: Fixed a bug when building programs with the length of the included file name...
[kolibrios.git] / drivers / audio / vt823x.asm
blobae19e58dfb696723921b3f257c533a4faea0d32f
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; ;;
3 ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4 ;; Distributed under terms of the GNU General Public License ;;
5 ;; ;;
6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 format PE DLL native 0.05
9 entry START
11 DEBUG equ 1
13 API_VERSION equ 0x01000100
15 IRQ_REMAP equ 0
16 IRQ_LINE equ 0
19 ;irq 0,13 unavailable
20 ; FEDCBA9876543210
21 VALID_IRQ equ 1101111111111110b
23 CPU_FREQ equ 2600d
25 BIT0 EQU 0x00000001
26 BIT1 EQU 0x00000002
27 BIT5 EQU 0x00000020
28 BIT10 EQU 0x00000400
30 VID_VIA equ 0x1106
32 CTRL_VT82C686 equ 0x3058
33 CTRL_VT8233_5 equ 0x3059
36 CODEC_MASTER_VOL_REG equ 0x02
37 CODEC_AUX_VOL equ 0x04 ;
38 CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume
39 CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
40 CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
41 CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
42 CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
43 CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
46 ;VIA host controller registers set
47 ;; common offsets
48 VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status
49 VIA_REG_STAT_ACTIVE equ 0x80 ;; RO
50 VIA_REG_STAT_PAUSED equ 0x40 ;; RO
51 VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO
52 VIA_REG_STAT_STOPPED equ 0x04 ;; RWC
53 VIA_REG_STAT_EOL equ 0x02 ;; RWC
54 VIA_REG_STAT_FLAG equ 0x01 ;; RWC
55 VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control
56 VIA_REG_CTRL_START equ 0x80 ;; WO
57 VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO
58 VIA_REG_CTRL_AUTOSTART equ 0x20
59 VIA_REG_CTRL_PAUSE equ 0x08 ;; RW
60 VIA_REG_CTRL_INT_STOP equ 0x04
61 VIA_REG_CTRL_INT_EOL equ 0x02
62 VIA_REG_CTRL_INT_FLAG equ 0x01
63 VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented
64 VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \
65 VIA_REG_CTRL_INT_EOL or \
66 VIA_REG_CTRL_AUTOSTART)
67 VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only)
68 VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL
69 VIA_REG_TYPE_16BIT equ 0x20 ;; RW
70 VIA_REG_TYPE_STEREO equ 0x10 ;; RW
71 VIA_REG_TYPE_INT_LLINE equ 0x00
72 VIA_REG_TYPE_INT_LSAMPLE equ 0x04
73 VIA_REG_TYPE_INT_LESSONE equ 0x08
74 VIA_REG_TYPE_INT_MASK equ 0x0c
75 VIA_REG_TYPE_INT_EOL equ 0x02
76 VIA_REG_TYPE_INT_FLAG equ 0x01
77 VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer
78 VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer
79 VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate
80 VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW
81 VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW
82 VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit)
83 VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only)
86 VIADEV_PLAYBACK equ 0x00
87 VIADEV_CAPTURE equ 0x10
88 VIADEV_FM equ 0x20
90 ;; AC'97 ;;
91 VIA_REG_AC97 equ 0x80 ; dword
92 VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30)
93 VIA_REG_AC97_CODEC_ID_SHIFT equ 30
94 VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00
95 VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01
96 VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27)
97 VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25)
98 VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24)
99 VIA_REG_AC97_READ equ 0x00800000 ;(1<<23)
100 VIA_REG_AC97_CMD_SHIFT equ 16
101 VIA_REG_AC97_CMD_MASK equ 0x7E
102 VIA_REG_AC97_DATA_SHIFT equ 0
103 VIA_REG_AC97_DATA_MASK equ 0xFFFF
105 VIA_REG_SGD_SHADOW equ 0x84 ; dword
107 ;; via8233-specific registers ;;
108 VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte
109 VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte
110 VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels
111 VIA_REG_MULTPLAY_FMT_8BIT equ 0x00
112 VIA_REG_MULTPLAY_FMT_16BIT equ 0x80
113 VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6)
114 VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable
115 VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40
117 VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33
119 VIA_TBL_BIT_FLAG equ 0x40000000
120 VIA_TBL_BIT_EOL equ 0x80000000
122 ;; pci space ;;
123 VIA_ACLINK_STAT equ 0x40
124 ;...
125 VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready
126 VIA_ACLINK_CTRL equ 0x41
127 VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable
128 VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert
129 VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi
130 VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi
131 VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA
132 VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM
133 VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only
134 VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only
135 VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \
136 VIA_ACLINK_CTRL_RESET or \
137 VIA_ACLINK_CTRL_PCM or \
138 VIA_ACLINK_CTRL_VRA)
139 VIA_FUNC_ENABLE equ 0x42
140 VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet!
141 VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented!
142 VIA_FUNC_RX2C_WRITE equ 0x20
143 VIA_FUNC_SB_FIFO_EMPTY equ 0x10
144 VIA_FUNC_ENABLE_GAME equ 0x08
145 VIA_FUNC_ENABLE_FM equ 0x04
146 VIA_FUNC_ENABLE_MIDI equ 0x02
147 VIA_FUNC_ENABLE_SB equ 0x01
148 VIA_PNP_CONTROL equ 0x43
149 VIA_FM_NMI_CTRL equ 0x48
150 VIA8233_VOLCHG_CTRL equ 0x48
151 VIA8233_SPDIF_CTRL equ 0x49
152 VIA8233_SPDIF_DX3 equ 0x08
153 VIA8233_SPDIF_SLOT_MASK equ 0x03
154 VIA8233_SPDIF_SLOT_1011 equ 0x00
155 VIA8233_SPDIF_SLOT_34 equ 0x01
156 VIA8233_SPDIF_SLOT_78 equ 0x02
157 VIA8233_SPDIF_SLOT_69 equ 0x03
158 ;] Asper
161 SRV_GETVERSION equ 0
162 DEV_PLAY equ 1
163 DEV_STOP equ 2
164 DEV_CALLBACK equ 3
165 DEV_SET_BUFF equ 4
166 DEV_NOTIFY equ 5
167 DEV_SET_MASTERVOL equ 6
168 DEV_GET_MASTERVOL equ 7
169 DEV_GET_INFO equ 8
170 DEV_GET_POS equ 9
172 struc AC_CNTRL ;AC controller base class
173 { .bus dd ?
174 .devfn dd ?
176 .vendor dd ?
177 .dev_id dd ?
178 .pci_cmd dd ?
179 .pci_stat dd ?
181 .codec_io_base dd ?
182 .codec_mem_base dd ?
184 .ctrl_io_base dd ?
185 .ctrl_mem_base dd ?
186 .cfg_reg dd ?
187 .int_line dd ?
189 .vendor_ids dd ? ;vendor id string
190 .ctrl_ids dd ? ;hub id string
192 .buffer dd ?
194 .notify_pos dd ?
195 .notify_task dd ?
197 .lvi_reg dd ?
198 .ctrl_setup dd ?
199 .user_callback dd ?
200 .codec_read16 dd ?
201 .codec_write16 dd ?
203 .ctrl_read8 dd ?
204 .ctrl_read16 dd ?
205 .ctrl_read32 dd ?
207 .ctrl_write8 dd ?
208 .ctrl_write16 dd ?
209 .ctrl_write32 dd ?
212 struc CODEC ;Audio Chip base class
214 .chip_id dd ?
215 .flags dd ?
216 .status dd ?
218 .ac_vendor_ids dd ? ;ac vendor id string
219 .chip_ids dd ? ;chip model string
221 .shadow_flag dd ?
222 dd ?
224 .regs dw ? ; codec registers
225 .reg_master_vol dw ? ;0x02
226 .reg_aux_out_vol dw ? ;0x04
227 .reg_mone_vol dw ? ;0x06
228 .reg_master_tone dw ? ;0x08
229 .reg_beep_vol dw ? ;0x0A
230 .reg_phone_vol dw ? ;0x0C
231 .reg_mic_vol dw ? ;0x0E
232 .reg_line_in_vol dw ? ;0x10
233 .reg_cd_vol dw ? ;0x12
234 .reg_video_vol dw ? ;0x14
235 .reg_aux_in_vol dw ? ;0x16
236 .reg_pcm_out_vol dw ? ;0x18
237 .reg_rec_select dw ? ;0x1A
238 .reg_rec_gain dw ? ;0x1C
239 .reg_rec_gain_mic dw ? ;0x1E
240 .reg_gen dw ? ;0x20
241 .reg_3d_ctrl dw ? ;0X22
242 .reg_page dw ? ;0X24
243 .reg_powerdown dw ? ;0x26
244 .reg_ext_audio dw ? ;0x28
245 .reg_ext_st dw ? ;0x2a
246 .reg_pcm_front_rate dw ? ;0x2c
247 .reg_pcm_surr_rate dw ? ;0x2e
248 .reg_lfe_rate dw ? ;0x30
249 .reg_pcm_in_rate dw ? ;0x32
250 dw ? ;0x34
251 .reg_cent_lfe_vol dw ? ;0x36
252 .reg_surr_vol dw ? ;0x38
253 .reg_spdif_ctrl dw ? ;0x3A
254 dw ? ;0x3C
255 dw ? ;0x3E
256 dw ? ;0x40
257 dw ? ;0x42
258 dw ? ;0x44
259 dw ? ;0x46
260 dw ? ;0x48
261 dw ? ;0x4A
262 dw ? ;0x4C
263 dw ? ;0x4E
264 dw ? ;0x50
265 dw ? ;0x52
266 dw ? ;0x54
267 dw ? ;0x56
268 dw ? ;0x58
269 dw ? ;0x5A
270 dw ? ;0x5C
271 dw ? ;0x5E
272 .reg_page_0 dw ? ;0x60
273 .reg_page_1 dw ? ;0x62
274 .reg_page_2 dw ? ;0x64
275 .reg_page_3 dw ? ;0x66
276 .reg_page_4 dw ? ;0x68
277 .reg_page_5 dw ? ;0x6A
278 .reg_page_6 dw ? ;0x6C
279 .reg_page_7 dw ? ;0x6E
280 dw ? ;0x70
281 dw ? ;0x72
282 dw ? ;0x74
283 dw ? ;0x76
284 dw ? ;0x78
285 dw ? ;0x7A
286 .reg_vendor_id_1 dw ? ;0x7C
287 .reg_vendor_id_2 dw ? ;0x7E
290 .reset dd ? ;virtual
291 .set_master_vol dd ?
294 struc CTRL_INFO
295 { .pci_cmd dd ?
296 .irq dd ?
297 .glob_cntrl dd ?
298 .glob_sta dd ?
299 .codec_io_base dd ?
300 .ctrl_io_base dd ?
301 .codec_mem_base dd ?
302 .ctrl_mem_base dd ?
303 .codec_id dd ?
306 EVENT_NOTIFY equ 0x00000200
308 section '.flat' code readable writable executable
309 include '../struct.inc'
310 include '../macros.inc'
311 include '../proc32.inc'
312 include '../peimport.inc'
314 proc START c, state:dword, cmdline:dword
316 cmp [state], 1
317 jne .stop
319 if DEBUG
320 mov esi, msgInit
321 invoke SysMsgBoardStr
322 end if
324 call detect_controller
325 test eax, eax
326 jz .fail
328 if DEBUG
329 mov esi, [ctrl.vendor_ids]
330 invoke SysMsgBoardStr
331 mov esi, [ctrl.ctrl_ids]
332 invoke SysMsgBoardStr
333 end if
335 call init_controller
336 test eax, eax
337 jz .fail
339 call init_codec
340 test eax, eax
341 jz .fail
343 call setup_codec
345 mov esi, msgPrimBuff
346 invoke SysMsgBoardStr
347 call create_primary_buff
348 mov esi, msgDone
349 invoke SysMsgBoardStr
351 if IRQ_REMAP
352 pushf
355 mov ebx, [ctrl.int_line]
356 in al, 0xA1
357 mov ah, al
358 in al, 0x21
359 test ebx, ebx
360 jz .skip
361 bts ax, bx ;mask old line
362 .skip:
363 bts ax, IRQ_LINE ;mask new ine
364 out 0x21, al
365 mov al, ah
366 out 0xA1, al
368 invoke PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ
370 mov dx, 0x4d0 ;8259 ELCR1
371 in al, dx
372 bts ax, IRQ_LINE
373 out dx, al ;set level-triggered mode
374 mov [ctrl.int_line], IRQ_LINE
375 popf
376 mov esi, msgRemap
377 invoke SysMsgBoardStr
378 end if
380 mov eax, VALID_IRQ
381 mov ebx, [ctrl.int_line]
382 mov esi, msgInvIRQ
383 bt eax, ebx
384 jnc .fail_msg
386 invoke AttachIntHandler, ebx, ac97_irq_VIA, 0
387 .reg:
388 invoke RegService, sz_sound_srv, service_proc
390 .fail:
391 if DEBUG
392 mov esi, msgFail
393 invoke SysMsgBoardStr
394 end if
395 xor eax, eax
397 .fail_msg:
398 invoke SysMsgBoardStr
399 xor eax, eax
401 .stop:
402 call stop
403 xor eax, eax
405 endp
407 handle equ IOCTL.handle
408 io_code equ IOCTL.io_code
409 input equ IOCTL.input
410 inp_size equ IOCTL.inp_size
411 output equ IOCTL.output
412 out_size equ IOCTL.out_size
414 align 4
415 proc service_proc stdcall, ioctl:dword
417 mov edi, [ioctl]
418 mov eax, [edi+io_code]
420 cmp eax, SRV_GETVERSION
421 jne @F
422 mov eax, [edi+output]
423 cmp [edi+out_size], 4
424 jne .fail
426 mov [eax], dword API_VERSION
427 xor eax, eax
430 cmp eax, DEV_PLAY
431 jne @F
432 if DEBUG
433 mov esi, msgPlay
434 invoke SysMsgBoardStr
435 end if
436 call play
439 cmp eax, DEV_STOP
440 jne @F
441 if DEBUG
442 mov esi, msgStop
443 invoke SysMsgBoardStr
444 end if
445 call stop
448 cmp eax, DEV_CALLBACK
449 jne @F
450 mov ebx, [edi+input]
451 stdcall set_callback, [ebx]
454 cmp eax, DEV_SET_MASTERVOL
455 jne @F
456 mov eax, [edi+input]
457 mov eax, [eax]
458 call set_master_vol ;eax= vol
461 cmp eax, DEV_GET_MASTERVOL
462 jne @F
463 mov ebx, [edi+output]
464 stdcall get_master_vol, ebx
467 cmp eax, DEV_GET_INFO
468 jne @F
469 mov ebx, [edi+output]
470 stdcall get_dev_info, ebx
473 cmp eax, DEV_GET_POS
474 jne @F
475 push ebx edx
476 mov edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CURR_COUNT
477 call [ctrl.ctrl_read32]
478 and eax, 0x00FFFFFF
479 mov ebx, 4096
480 sub ebx, eax
481 shr ebx, 2
482 mov edx, [edi+output]
483 mov [edx], ebx
484 pop edx ebx
487 .fail:
488 or eax, -1
490 endp
492 restore handle
493 restore io_code
494 restore input
495 restore inp_size
496 restore output
497 restore out_size
500 align 4
501 proc ac97_irq_VIA
502 locals
503 status db 0
504 endl
506 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
507 call [ctrl.ctrl_read8]
508 test al, VIA_REG_STAT_ACTIVE
509 jz @f
511 and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED
512 mov byte [status], al
514 mov ebx, dword [buff_list]
515 cmp [ctrl.user_callback], 0
516 je @f
517 stdcall [ctrl.user_callback], ebx
519 mov al, byte [status] ;; ack ;;
520 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
521 call [ctrl.ctrl_write8]
524 endp
527 align 4
528 proc create_primary_buff
530 invoke KernelAlloc, 0x10000
531 mov [ctrl.buffer], eax
533 mov edi, eax
534 mov ecx, 0x10000/4
535 xor eax, eax
537 rep stosd
539 mov eax, [ctrl.buffer]
540 invoke GetPgAddr
541 mov edi, pcmout_bdl
542 stosd
543 mov eax, 0x80004000
544 stosd
546 mov edi, buff_list
547 mov eax, [ctrl.buffer]
548 mov ecx, 4
550 mov [edi], eax
551 mov [edi+16], eax
552 mov [edi+32], eax
553 mov [edi+48], eax
554 mov [edi+64], eax
555 mov [edi+80], eax
556 mov [edi+96], eax
557 mov [edi+112], eax
559 ;add eax, 0x4000
560 add edi, 4
561 loop @B
563 stdcall channel_reset, VIADEV_PLAYBACK
564 stdcall codec_check_ready
566 mov eax, pcmout_bdl
567 mov ebx, eax
568 invoke GetPgAddr
569 and ebx, 0xFFF
570 add eax, ebx
572 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
573 call [ctrl.ctrl_write32]
575 stdcall codec_check_ready
577 mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L
578 mov eax, 7 ;31
579 call [ctrl.ctrl_write8]
581 mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R
582 mov eax, 7 ;31
583 call [ctrl.ctrl_write8]
585 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
586 mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
587 mov [ctrl.lvi_reg], 16 ;0xF;eax
588 call [ctrl.ctrl_write32]
590 stdcall codec_check_ready
592 endp
595 proc channel_reset channel:dword
596 mov esi, dword [channel]
597 mov edx, esi
598 add edx, VIA_REG_OFFSET_CONTROL
599 mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET
600 call [ctrl.ctrl_write8]
602 mov edx, esi
603 add edx, VIA_REG_OFFSET_CONTROL
604 call [ctrl.ctrl_read8]
606 mov eax, 50000 ; wait 50 ms
607 call StallExec
608 ; disable interrupts
609 mov edx, esi
610 add edx, VIA_REG_OFFSET_CONTROL
611 xor eax, eax
612 call [ctrl.ctrl_write8]
614 ; clear interrupts
615 mov edx, esi
616 add edx, VIA_REG_OFFSET_STATUS
617 mov eax, 0x03
618 call [ctrl.ctrl_write8]
620 ;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
621 ; mov edx, esi ;; for via686
622 ; add edx, VIA_REG_OFFSET_TYPE
623 ; mov eax, 0x03
624 ; call [ctrl.ctrl_write8]
626 ;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
627 ;mov edx, esi
628 ;add edx, VIA_REG_OFFSET_CURR_PTR
629 ;xor eax, eax
630 ;call [ctrl.ctrl_write8]
633 endp
636 align 4
637 proc detect_controller
638 locals
639 last_bus dd ?
640 bus dd ?
641 devfn dd ?
642 endl
644 xor eax, eax
645 mov [bus], eax
646 inc eax
647 invoke PciApi
648 cmp eax, -1
649 je .err
651 mov [last_bus], eax
653 .next_bus:
654 and [devfn], 0
655 .next_dev:
656 invoke PciRead32, [bus], [devfn], dword 0
657 test eax, eax
658 jz .next
659 cmp eax, -1
660 je .next
662 mov edi, devices
664 mov ebx, [edi]
665 test ebx, ebx
666 jz .next
668 cmp eax, ebx
669 je .found
670 add edi, 12
671 jmp @B
672 .next:
673 inc [devfn]
674 cmp [devfn], 256
675 jb .next_dev
676 mov eax, [bus]
677 inc eax
678 mov [bus], eax
679 cmp eax, [last_bus]
680 jna .next_bus
681 xor eax, eax
683 .found:
684 mov ebx, [bus]
685 mov [ctrl.bus], ebx
687 mov ecx, [devfn]
688 mov [ctrl.devfn], ecx
690 mov edx, eax
691 and edx, 0xFFFF
692 mov [ctrl.vendor], edx
693 shr eax, 16
694 mov [ctrl.dev_id], eax
696 mov ebx, [edi+4]
697 mov [ctrl.ctrl_ids], ebx
698 mov esi, [edi+8]
699 mov [ctrl.ctrl_setup], esi
701 cmp edx, VID_VIA
702 jne @F
703 mov [ctrl.vendor_ids], msg_VIA
707 .err:
708 xor eax, eax
709 mov [ctrl.vendor_ids], eax ;something wrong ?
711 endp
713 align 4
714 proc init_controller
716 invoke PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
717 mov ebx, eax
718 and eax, 0xFFFF
719 mov [ctrl.pci_cmd], eax
720 shr ebx, 16
721 mov [ctrl.pci_stat], ebx
723 mov esi, msgPciCmd
724 invoke SysMsgBoardStr
725 call dword2str
726 invoke SysMsgBoardStr
728 mov esi, msgPciStat
729 invoke SysMsgBoardStr
730 mov eax, [ctrl.pci_stat]
731 call dword2str
732 invoke SysMsgBoardStr
734 mov esi, msgCtrlIsaIo
735 invoke SysMsgBoardStr
736 invoke PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
737 call dword2str
738 invoke SysMsgBoardStr
740 and eax, 0xFFC0
741 mov [ctrl.ctrl_io_base], eax
743 .default:
744 invoke PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
745 and eax, 0xFF
747 mov [ctrl.int_line], eax
749 ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42
750 ;mov byte [old_legacy], al
752 ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43
753 ;mov byte [old_legacy_cfg], al
755 ;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM
756 ;xor al, 0xFF
757 ;and al, byte [old_legacy]
758 ;and eax, 0xFF
759 ;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42
760 ;mov byte [old_legacy], al
762 call [ctrl.ctrl_setup]
763 xor eax, eax
764 inc eax
766 endp
768 align 4
769 proc set_VIA
770 mov [ctrl.codec_read16], codec_io_r16 ;virtual
771 mov [ctrl.codec_write16], codec_io_w16 ;virtual
773 mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
774 mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
775 mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
777 mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
778 mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
779 mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
781 endp
784 align 4
785 proc init_codec
786 locals
787 counter dd ?
788 endl
790 mov esi, msgControl
791 invoke SysMsgBoardStr
792 invoke PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
793 and eax, 0xFF
794 call dword2str
795 invoke SysMsgBoardStr
797 mov esi, msgStatus
798 invoke SysMsgBoardStr
799 invoke PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
800 and eax, 0xFF
801 push eax
802 call dword2str
803 invoke SysMsgBoardStr
804 pop eax
806 test eax, VIA_ACLINK_C00_READY
807 jnz .ready
809 call reset_codec
810 test eax, eax
811 jz .err
813 .ready:
814 xor edx, edx ; ac_reg_0
815 call [ctrl.codec_write16]
816 jmp .done
818 .err:
819 xor eax, eax ; timeout error
822 .done:
823 call detect_codec
825 xor eax, eax
826 inc eax
828 endp
830 align 4
831 proc reset_codec
832 invoke PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \
833 VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC
834 mov eax, 100000 ; wait 100 ms
835 call StallExec
836 .cold:
837 call cold_reset
838 jnc .ok
840 if DEBUG
841 mov esi, msgCFail
842 invoke SysMsgBoardStr
843 end if
844 xor eax, eax ; timeout error
846 .ok:
847 if DEBUG
848 mov esi, msgResetOk
849 invoke SysMsgBoardStr
850 end if
851 xor eax, eax
852 inc eax
854 endp
857 align 4
858 proc cold_reset
859 locals
860 counter dd ?
861 endl
863 invoke PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0
865 if DEBUG
866 mov esi, msgCold
867 invoke SysMsgBoardStr
868 end if
870 mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms
871 call StallExec
873 ;; ACLink on, deassert ACLink reset, VSR, SGD data out
874 ;; note - FM data out has trouble with non VRA codecs !!
875 invoke PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT
877 mov [counter], 16 ; total 20*100 ms = 2s
878 .wait:
879 invoke PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
880 test eax, VIA_ACLINK_C00_READY
881 jnz .ok
883 mov eax, 100000 ; wait 100 ms
884 call StallExec
886 dec [counter]
887 jnz .wait
889 if DEBUG
890 mov esi, msgCRFail
891 invoke SysMsgBoardStr
892 end if
894 .fail:
897 .ok:
898 mov esi, msgControl
899 invoke SysMsgBoardStr
900 invoke PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
901 call dword2str
902 invoke SysMsgBoardStr
904 mov esi, msgStatus
905 invoke SysMsgBoardStr
906 invoke PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
907 and eax, 0xFF
908 push eax
909 call dword2str
910 invoke SysMsgBoardStr
911 pop eax
913 test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY
914 jz .fail
917 endp
919 align 4
920 play:
921 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
922 mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
923 mov [ctrl.lvi_reg], 16
924 call [ctrl.ctrl_write32]
926 mov eax, VIA_REG_CTRL_INT
927 or eax, VIA_REG_CTRL_START
928 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
929 call [ctrl.ctrl_write8]
931 xor eax, eax
934 align 4
935 stop:
936 mov eax, VIA_REG_CTRL_INT
937 or eax, VIA_REG_CTRL_TERMINATE
938 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
939 call [ctrl.ctrl_write8]
941 stdcall channel_reset, VIADEV_PLAYBACK
942 xor eax, eax
945 align 4
946 proc get_dev_info stdcall, p_info:dword
947 virtual at esi
948 CTRL_INFO CTRL_INFO
949 end virtual
951 mov esi, [p_info]
952 mov eax, [ctrl.int_line]
953 mov ecx, [ctrl.ctrl_io_base]
954 mov [CTRL_INFO.irq], eax
955 mov [CTRL_INFO.ctrl_io_base], ecx
957 xor eax, eax
958 ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
959 ;call [ctrl.ctrl_read32]
960 mov [CTRL_INFO.codec_io_base], eax
961 ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
962 ;call [ctrl.ctrl_read32]
963 mov [CTRL_INFO.codec_mem_base], eax
964 ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT
965 ;call [ctrl.ctrl_read32]
966 mov [CTRL_INFO.ctrl_mem_base], eax
968 mov eax, [codec.chip_id]
969 mov [CTRL_INFO.codec_id], eax
971 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
972 call [ctrl.ctrl_read8]
973 and eax, 0xFF
974 mov [CTRL_INFO.glob_cntrl], eax
976 mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
977 call [ctrl.ctrl_read8]
978 and eax, 0xFF
979 mov [CTRL_INFO.glob_sta], eax
981 mov ebx, [ctrl.pci_cmd]
982 mov [CTRL_INFO.pci_cmd], ebx
984 endp
986 align 4
987 proc set_callback stdcall, handler:dword
988 mov eax, [handler]
989 mov [ctrl.user_callback], eax
991 endp
994 align 4
995 proc codec_check_ready stdcall
996 locals
997 counter dd ?
998 endl
1000 mov [counter], 1000 ; total 1000*1 ms = 1s
1001 .wait:
1002 call [ctrl.codec_read16]
1003 test eax, VIA_REG_AC97_BUSY
1004 jz .ok
1006 mov eax, 1000 ; wait 1 ms
1007 call StallExec
1009 sub [counter] , 1
1010 jnz .wait
1011 .err:
1012 mov eax, -1
1014 .ok:
1015 and eax, 0xFFFF
1017 endp
1020 align 4
1021 proc codec_valid stdcall
1022 stdcall codec_check_ready
1024 endp
1026 align 4
1027 proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
1028 locals
1029 counter dd ?
1030 endl
1032 ;Use only primary codec.
1033 mov eax, [ac_reg]
1034 and eax, 0x7F
1035 shl eax, VIA_REG_AC97_CMD_SHIFT
1036 or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ
1038 mov [counter], 3 ; total 3*20 ms = 60ms
1039 .wait:
1040 push eax
1041 call [ctrl.codec_write16]
1043 mov eax, 20000 ; wait 20 ms
1044 call StallExec
1046 stdcall codec_valid
1047 cmp eax, 0
1048 pop eax
1049 jge .ok
1051 sub [counter] , 1
1052 jnz .wait
1053 jmp .err
1055 .ok:
1056 mov eax, 25000 ; wait 25 ms
1057 call StallExec
1059 call [ctrl.codec_read16] ;change edx !!!
1060 and eax, 0xFFFF
1062 .err:
1063 if DEBUG
1064 mov esi, msgCInvalid
1065 invoke SysMsgBoardStr
1066 end if
1067 mov eax, -1 ; invalid codec error
1069 endp
1071 align 4
1072 proc codec_write stdcall, ac_reg:dword
1073 ;Use only primary codec.
1074 mov esi, [ac_reg]
1075 mov edx, esi
1076 shl edx, VIA_REG_AC97_CMD_SHIFT
1078 shl eax, VIA_REG_AC97_DATA_SHIFT
1079 or edx, eax
1081 mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY
1082 shl eax, VIA_REG_AC97_CODEC_ID_SHIFT
1083 or edx, eax
1085 mov eax, edx
1086 mov edx, esi
1087 call [ctrl.codec_write16]
1088 mov [codec.regs+esi], ax
1090 stdcall codec_check_ready
1091 cmp eax, 0
1092 jl .err
1093 .ok:
1095 .err:
1096 if DEBUG
1097 mov esi, msgCFail
1098 invoke SysMsgBoardStr
1099 end if
1100 ;mov eax, -1 ; codec not ready error
1102 endp
1104 align 4
1105 proc StallExec
1106 push ecx
1107 push edx
1108 push ebx
1109 push eax
1111 mov ecx, CPU_FREQ
1112 mul ecx
1113 mov ebx, eax ;low
1114 mov ecx, edx ;high
1115 rdtsc
1116 add ebx, eax
1117 adc ecx, edx
1119 rdtsc
1120 sub eax, ebx
1121 sbb edx, ecx
1122 js @B
1124 pop eax
1125 pop ebx
1126 pop edx
1127 pop ecx
1129 endp
1131 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1132 ; CONTROLLER IO functions
1133 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1135 align 4
1136 proc codec_io_r16 ;r32
1137 mov edx, [ctrl.ctrl_io_base]
1138 add edx, VIA_REG_AC97
1139 in eax, dx
1141 endp
1143 align 4
1144 proc codec_io_w16 ;w32
1145 mov edx, [ctrl.ctrl_io_base]
1146 add edx, VIA_REG_AC97
1147 out dx, eax
1149 endp
1151 align 4
1152 proc ctrl_io_r8
1153 add edx, [ctrl.ctrl_io_base]
1154 in al, dx
1156 endp
1158 align 4
1159 proc ctrl_io_r16
1160 add edx, [ctrl.ctrl_io_base]
1161 in ax, dx
1163 endp
1165 align 4
1166 proc ctrl_io_r32
1167 add edx, [ctrl.ctrl_io_base]
1168 in eax, dx
1170 endp
1172 align 4
1173 proc ctrl_io_w8
1174 add edx, [ctrl.ctrl_io_base]
1175 out dx, al
1177 endp
1179 align 4
1180 proc ctrl_io_w16
1181 add edx, [ctrl.ctrl_io_base]
1182 out dx, ax
1184 endp
1186 align 4
1187 proc ctrl_io_w32
1188 add edx, [ctrl.ctrl_io_base]
1189 out dx, eax
1191 endp
1194 align 4
1195 dword2str:
1196 push eax ebx ecx
1197 mov esi, hex_buff
1198 mov ecx, -8
1200 rol eax, 4
1201 mov ebx, eax
1202 and ebx, 0x0F
1203 mov bl, [ebx+hexletters]
1204 mov [8+esi+ecx], bl
1205 inc ecx
1206 jnz @B
1207 pop ecx ebx eax
1210 hexletters db '0123456789ABCDEF'
1211 hex_buff db 8 dup(0),13,10,0
1214 include "codec.inc"
1216 align 4
1217 devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA
1218 dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA
1219 dd 0 ;terminator
1222 msg_VT82C686 db 'VT82C686', 13,10, 0
1223 msg_VT8233 db 'VT8233', 13,10, 0
1224 msg_VIA db 'VIA' , 13,10, 0
1226 szKernel db 'KERNEL', 0
1227 sz_sound_srv db 'SOUND',0
1229 msgInit db 'detect hardware...',13,10,0
1230 msgFail db 'device not found',13,10,0
1231 msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0
1232 msgPlay db 'start play', 13,10,0
1233 msgStop db 'stop play', 13,10,0
1234 ;msgIRQ db 'AC97 IRQ', 13,10,0
1235 ;msgInitCtrl db 'init controller',13,10,0
1236 ;msgInitCodec db 'init codec',13,10,0
1237 msgPrimBuff db 'create primary buffer ...',0
1238 msgDone db 'done',13,10,0
1239 msgRemap db 'Remap IRQ',13,10,0
1240 ;msgReg db 'set service handler',13,10,0
1241 ;msgOk db 'service installed',13,10,0
1242 msgCold db 'cold reset',13,10,0
1243 ;msgWarm db 'warm reset',13,10,0
1244 ;msgWRFail db 'warm reset failed',13,10,0
1245 msgCRFail db 'cold reset failed',13,10,0
1246 msgCFail db 'codec not ready',13,10,0
1247 msgCInvalid db 'codec is not valid',13,10,0 ;Asper
1248 msgResetOk db 'reset complete',13,10,0
1249 msgStatus db 'global status ',0
1250 msgControl db 'global control ',0
1251 msgPciCmd db 'PCI command ',0
1252 msgPciStat db 'PCI status ',0
1253 msgCtrlIsaIo db 'controller io base ',0
1254 ;msgMixIsaIo db 'codec io base ',0
1255 ;msgCtrlMMIo db 'controller mmio base ',0
1256 ;msgMixMMIo db 'codec mmio base ',0
1257 ;msgIrqMap db 'AC97 irq map as ',0
1259 align 4
1260 data fixups
1261 end data
1263 align 8
1264 pcmout_bdl rq 32
1265 buff_list rd 32
1267 codec CODEC
1268 ctrl AC_CNTRL
1270 chip_type rb 1