diff --git a/kernel/trunk/build.bat b/kernel/trunk/build.bat index d94ebd06c6..ca024c9848 100644 --- a/kernel/trunk/build.bat +++ b/kernel/trunk/build.bat @@ -1,7 +1,7 @@ @echo off cls set languages=en ru ge et -set drivers=com_mouse emu10k1x ensoniq fm801 infinity sis sound uart viasound vmode vt823(x) +set drivers=com_mouse emu10k1x ensoniq fm801 infinity sis sound uart viasound vmode vt823x set targets=all kernel drivers skins clean call :Check_Target %1 diff --git a/kernel/trunk/drivers/vt823(x).asm b/kernel/trunk/drivers/vt823x.asm similarity index 95% rename from kernel/trunk/drivers/vt823(x).asm rename to kernel/trunk/drivers/vt823x.asm index 18dbef9068..51de417386 100644 --- a/kernel/trunk/drivers/vt823(x).asm +++ b/kernel/trunk/drivers/vt823x.asm @@ -1,1281 +1,1281 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -format MS COFF - -DEBUG equ 1 - -include 'proc32.inc' -include 'imports.inc' - -API_VERSION equ 0x01000100 - -USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices -IRQ_REMAP equ 0 -IRQ_LINE equ 0 - - -;irq 0,1,2,8,12,13 недоступны -; FEDCBA9876543210 -VALID_IRQ equ 1100111011111000b -ATTCH_IRQ equ 0000111010100000b - -if USE_COM_IRQ -ATTCH_IRQ equ 0000111010111000b -end if - -CPU_FREQ equ 2600d - -BIT0 EQU 0x00000001 -BIT1 EQU 0x00000002 -BIT5 EQU 0x00000020 -BIT10 EQU 0x00000400 - -VID_VIA equ 0x1106 - -CTRL_VT82C686 equ 0x3058 -CTRL_VT8233_5 equ 0x3059 - - -CODEC_MASTER_VOL_REG equ 0x02 -CODEC_AUX_VOL equ 0x04 ; -CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume -CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio -CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control -CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate -CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate -CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate - - -;VIA host controller registers set -;; common offsets -VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status - VIA_REG_STAT_ACTIVE equ 0x80 ;; RO - VIA_REG_STAT_PAUSED equ 0x40 ;; RO - VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO - VIA_REG_STAT_STOPPED equ 0x04 ;; RWC - VIA_REG_STAT_EOL equ 0x02 ;; RWC - VIA_REG_STAT_FLAG equ 0x01 ;; RWC -VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control - VIA_REG_CTRL_START equ 0x80 ;; WO - VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO - VIA_REG_CTRL_AUTOSTART equ 0x20 - VIA_REG_CTRL_PAUSE equ 0x08 ;; RW - VIA_REG_CTRL_INT_STOP equ 0x04 - VIA_REG_CTRL_INT_EOL equ 0x02 - VIA_REG_CTRL_INT_FLAG equ 0x01 - VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented - VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \ - VIA_REG_CTRL_INT_EOL or \ - VIA_REG_CTRL_AUTOSTART) -VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only) - VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL - VIA_REG_TYPE_16BIT equ 0x20 ;; RW - VIA_REG_TYPE_STEREO equ 0x10 ;; RW - VIA_REG_TYPE_INT_LLINE equ 0x00 - VIA_REG_TYPE_INT_LSAMPLE equ 0x04 - VIA_REG_TYPE_INT_LESSONE equ 0x08 - VIA_REG_TYPE_INT_MASK equ 0x0c - VIA_REG_TYPE_INT_EOL equ 0x02 - VIA_REG_TYPE_INT_FLAG equ 0x01 -VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer -VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer -VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate - VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW - VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW -VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit) -VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only) - - -VIADEV_PLAYBACK equ 0x00 -VIADEV_CAPTURE equ 0x10 -VIADEV_FM equ 0x20 - -;; AC'97 ;; -VIA_REG_AC97 equ 0x80 ; dword - VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30) - VIA_REG_AC97_CODEC_ID_SHIFT equ 30 - VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00 - VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01 - VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27) - VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25) - VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24) - VIA_REG_AC97_READ equ 0x00800000 ;(1<<23) - VIA_REG_AC97_CMD_SHIFT equ 16 - VIA_REG_AC97_CMD_MASK equ 0x7E - VIA_REG_AC97_DATA_SHIFT equ 0 - VIA_REG_AC97_DATA_MASK equ 0xFFFF - -VIA_REG_SGD_SHADOW equ 0x84 ; dword - -;; via8233-specific registers ;; -VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte -VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte -VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels - VIA_REG_MULTPLAY_FMT_8BIT equ 0x00 - VIA_REG_MULTPLAY_FMT_16BIT equ 0x80 - VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6) -VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable - VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40 - -VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33 - -VIA_TBL_BIT_FLAG equ 0x40000000 -VIA_TBL_BIT_EOL equ 0x80000000 - -;; pci space ;; -VIA_ACLINK_STAT equ 0x40 - ;... - VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready -VIA_ACLINK_CTRL equ 0x41 - VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable - VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert - VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi - VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi - VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA - VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM - VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only - VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only - VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \ - VIA_ACLINK_CTRL_RESET or \ - VIA_ACLINK_CTRL_PCM or \ - VIA_ACLINK_CTRL_VRA) -VIA_FUNC_ENABLE equ 0x42 - VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet! - VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented! - VIA_FUNC_RX2C_WRITE equ 0x20 - VIA_FUNC_SB_FIFO_EMPTY equ 0x10 - VIA_FUNC_ENABLE_GAME equ 0x08 - VIA_FUNC_ENABLE_FM equ 0x04 - VIA_FUNC_ENABLE_MIDI equ 0x02 - VIA_FUNC_ENABLE_SB equ 0x01 -VIA_PNP_CONTROL equ 0x43 -VIA_FM_NMI_CTRL equ 0x48 -VIA8233_VOLCHG_CTRL equ 0x48 -VIA8233_SPDIF_CTRL equ 0x49 - VIA8233_SPDIF_DX3 equ 0x08 - VIA8233_SPDIF_SLOT_MASK equ 0x03 - VIA8233_SPDIF_SLOT_1011 equ 0x00 - VIA8233_SPDIF_SLOT_34 equ 0x01 - VIA8233_SPDIF_SLOT_78 equ 0x02 - VIA8233_SPDIF_SLOT_69 equ 0x03 -;] Asper - - -SRV_GETVERSION equ 0 -DEV_PLAY equ 1 -DEV_STOP equ 2 -DEV_CALLBACK equ 3 -DEV_SET_BUFF equ 4 -DEV_NOTIFY equ 5 -DEV_SET_MASTERVOL equ 6 -DEV_GET_MASTERVOL equ 7 -DEV_GET_INFO equ 8 - -struc AC_CNTRL ;AC controller base class -{ .bus dd ? - .devfn dd ? - - .vendor dd ? - .dev_id dd ? - .pci_cmd dd ? - .pci_stat dd ? - - .codec_io_base dd ? - .codec_mem_base dd ? - - .ctrl_io_base dd ? - .ctrl_mem_base dd ? - .cfg_reg dd ? - .int_line dd ? - - .vendor_ids dd ? ;vendor id string - .ctrl_ids dd ? ;hub id string - - .buffer dd ? - - .notify_pos dd ? - .notify_task dd ? - - .lvi_reg dd ? - .ctrl_setup dd ? - .user_callback dd ? - .codec_read16 dd ? - .codec_write16 dd ? - - .ctrl_read8 dd ? - .ctrl_read16 dd ? - .ctrl_read32 dd ? - - .ctrl_write8 dd ? - .ctrl_write16 dd ? - .ctrl_write32 dd ? -} - -struc CODEC ;Audio Chip base class -{ - .chip_id dd ? - .flags dd ? - .status dd ? - - .ac_vendor_ids dd ? ;ac vendor id string - .chip_ids dd ? ;chip model string - - .shadow_flag dd ? - dd ? - - .regs dw ? ; codec registers - .reg_master_vol dw ? ;0x02 - .reg_aux_out_vol dw ? ;0x04 - .reg_mone_vol dw ? ;0x06 - .reg_master_tone dw ? ;0x08 - .reg_beep_vol dw ? ;0x0A - .reg_phone_vol dw ? ;0x0C - .reg_mic_vol dw ? ;0x0E - .reg_line_in_vol dw ? ;0x10 - .reg_cd_vol dw ? ;0x12 - .reg_video_vol dw ? ;0x14 - .reg_aux_in_vol dw ? ;0x16 - .reg_pcm_out_vol dw ? ;0x18 - .reg_rec_select dw ? ;0x1A - .reg_rec_gain dw ? ;0x1C - .reg_rec_gain_mic dw ? ;0x1E - .reg_gen dw ? ;0x20 - .reg_3d_ctrl dw ? ;0X22 - .reg_page dw ? ;0X24 - .reg_powerdown dw ? ;0x26 - .reg_ext_audio dw ? ;0x28 - .reg_ext_st dw ? ;0x2a - .reg_pcm_front_rate dw ? ;0x2c - .reg_pcm_surr_rate dw ? ;0x2e - .reg_lfe_rate dw ? ;0x30 - .reg_pcm_in_rate dw ? ;0x32 - dw ? ;0x34 - .reg_cent_lfe_vol dw ? ;0x36 - .reg_surr_vol dw ? ;0x38 - .reg_spdif_ctrl dw ? ;0x3A - dw ? ;0x3C - dw ? ;0x3E - dw ? ;0x40 - dw ? ;0x42 - dw ? ;0x44 - dw ? ;0x46 - dw ? ;0x48 - dw ? ;0x4A - dw ? ;0x4C - dw ? ;0x4E - dw ? ;0x50 - dw ? ;0x52 - dw ? ;0x54 - dw ? ;0x56 - dw ? ;0x58 - dw ? ;0x5A - dw ? ;0x5C - dw ? ;0x5E - .reg_page_0 dw ? ;0x60 - .reg_page_1 dw ? ;0x62 - .reg_page_2 dw ? ;0x64 - .reg_page_3 dw ? ;0x66 - .reg_page_4 dw ? ;0x68 - .reg_page_5 dw ? ;0x6A - .reg_page_6 dw ? ;0x6C - .reg_page_7 dw ? ;0x6E - dw ? ;0x70 - dw ? ;0x72 - dw ? ;0x74 - dw ? ;0x76 - dw ? ;0x78 - dw ? ;0x7A - .reg_vendor_id_1 dw ? ;0x7C - .reg_vendor_id_2 dw ? ;0x7E - - - .reset dd ? ;virual - .set_master_vol dd ? -} - -struc CTRL_INFO -{ .pci_cmd dd ? - .irq dd ? - .glob_cntrl dd ? - .glob_sta dd ? - .codec_io_base dd ? - .ctrl_io_base dd ? - .codec_mem_base dd ? - .ctrl_mem_base dd ? - .codec_id dd ? -} - -struc IOCTL -{ .handle dd ? - .io_code dd ? - .input dd ? - .inp_size dd ? - .output dd ? - .out_size dd ? -} - -virtual at 0 - IOCTL IOCTL -end virtual - -EVENT_NOTIFY equ 0x00000200 - -public START -public service_proc -public version - -section '.flat' code readable align 16 - -proc START stdcall, state:dword - - cmp [state], 1 - jne .stop - - if DEBUG - mov esi, msgInit - call SysMsgBoardStr - end if - - call detect_controller - test eax, eax - jz .fail - - if DEBUG - mov esi,[ctrl.vendor_ids] - call SysMsgBoardStr - mov esi, [ctrl.ctrl_ids] - call SysMsgBoardStr - end if - - call init_controller - test eax, eax - jz .fail - - call init_codec - test eax, eax - jz .fail - - call setup_codec - - mov esi, msgPrimBuff - call SysMsgBoardStr - call create_primary_buff - mov esi, msgDone - call SysMsgBoardStr - - if IRQ_REMAP - pushf - cli - - mov ebx, [ctrl.int_line] - in al, 0xA1 - mov ah, al - in al, 0x21 - test ebx, ebx - jz .skip - bts ax, bx ;mask old line -.skip: - bts ax, IRQ_LINE ;mask new ine - out 0x21, al - mov al, ah - out 0xA1, al - - stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ - - mov dx, 0x4d0 ;8259 ELCR1 - in al, dx - bts ax, IRQ_LINE - out dx, al ;set level-triggered mode - mov [ctrl.int_line], IRQ_LINE - popf - mov esi, msgRemap - call SysMsgBoardStr - end if - - mov eax, VALID_IRQ - mov ebx, [ctrl.int_line] - mov esi, msgInvIRQ - bt eax, ebx - jnc .fail_msg - mov eax, ATTCH_IRQ - mov esi, msgAttchIRQ - bt eax, ebx - jnc .fail_msg - - stdcall AttachIntHandler, ebx, ac97_irq_VIA, dword 0 -.reg: - stdcall RegService, sz_sound_srv, service_proc - ret -.fail: - if DEBUG - mov esi, msgFail - call SysMsgBoardStr - end if - xor eax, eax - ret -.fail_msg: - call SysMsgBoardStr - xor eax, eax - ret -.stop: - call stop - xor eax, eax - ret -endp - -handle equ IOCTL.handle -io_code equ IOCTL.io_code -input equ IOCTL.input -inp_size equ IOCTL.inp_size -output equ IOCTL.output -out_size equ IOCTL.out_size - -align 4 -proc service_proc stdcall, ioctl:dword - - mov edi, [ioctl] - mov eax, [edi+io_code] - - cmp eax, SRV_GETVERSION - jne @F - mov eax, [edi+output] - cmp [edi+out_size], 4 - jne .fail - - mov [eax], dword API_VERSION - xor eax, eax - ret -@@: - cmp eax, DEV_PLAY - jne @F - if DEBUG - mov esi, msgPlay - call SysMsgBoardStr - end if - call play - ret -@@: - cmp eax, DEV_STOP - jne @F - if DEBUG - mov esi, msgStop - call SysMsgBoardStr - end if - call stop - ret -@@: - cmp eax, DEV_CALLBACK - jne @F - mov ebx, [edi+input] - stdcall set_callback, [ebx] - ret -@@: - cmp eax, DEV_SET_MASTERVOL - jne @F - mov eax, [edi+input] - mov eax, [eax] - call set_master_vol ;eax= vol - ret -@@: - cmp eax, DEV_GET_MASTERVOL - jne @F - mov ebx, [edi+output] - stdcall get_master_vol, ebx - ret -@@: - cmp eax, DEV_GET_INFO - jne @F - mov ebx, [edi+output] - stdcall get_dev_info, ebx - ret -@@: -.fail: - or eax, -1 - ret -endp - -restore handle -restore io_code -restore input -restore inp_size -restore output -restore out_size - - -align 4 -proc ac97_irq_VIA - locals - status db 0 - endl - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS - call [ctrl.ctrl_read8] - test al, VIA_REG_STAT_ACTIVE - jz @f - - and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED - mov byte [status], al - - mov ebx, dword [buff_list] - cmp [ctrl.user_callback], 0 - je @f - stdcall [ctrl.user_callback], ebx - @@: - mov al, byte [status] ;; ack ;; - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS - call [ctrl.ctrl_write8] - - ret -endp - - -align 4 -proc create_primary_buff - - stdcall KernelAlloc, 0x10000 - mov [ctrl.buffer], eax - - mov edi, eax - mov ecx, 0x10000/4 - xor eax, eax - cld - rep stosd - - mov eax, [ctrl.buffer] - call GetPgAddr - mov edi, pcmout_bdl - stosd - mov eax, 0x80004000 - stosd - - mov edi, buff_list - mov eax, [ctrl.buffer] - mov ecx, 4 -@@: - mov [edi], eax - mov [edi+16], eax - mov [edi+32], eax - mov [edi+48], eax - mov [edi+64], eax - mov [edi+80], eax - mov [edi+96], eax - mov [edi+112], eax - - ;add eax, 0x4000 - add edi, 4 - loop @B - - stdcall channel_reset, VIADEV_PLAYBACK - stdcall codec_check_ready - - mov eax, pcmout_bdl - mov ebx, eax - call GetPgAddr - and ebx, 0xFFF - add eax, ebx - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR - call [ctrl.ctrl_write32] - - stdcall codec_check_ready - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L - mov eax, 7;31 - call [ctrl.ctrl_write8] - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R - mov eax, 7;31 - call [ctrl.ctrl_write8] - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX - mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000 - mov [ctrl.lvi_reg], 16;0xF;eax - call [ctrl.ctrl_write32] - - stdcall codec_check_ready - ret -endp - - -proc channel_reset channel:dword - mov esi, dword [channel] - mov edx, esi - add edx, VIA_REG_OFFSET_CONTROL - mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET - call [ctrl.ctrl_write8] - - mov edx, esi - add edx, VIA_REG_OFFSET_CONTROL - call [ctrl.ctrl_read8] - - mov eax, 50000 ; wait 50 ms - call StallExec - ; disable interrupts - mov edx, esi - add edx, VIA_REG_OFFSET_CONTROL - xor eax, eax - call [ctrl.ctrl_write8] - - ; clear interrupts - mov edx, esi - add edx, VIA_REG_OFFSET_STATUS - mov eax, 0x03 - call [ctrl.ctrl_write8] - - ;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */ - ; mov edx, esi ;; for via686 - ; add edx, VIA_REG_OFFSET_TYPE - ; mov eax, 0x03 - ; call [ctrl.ctrl_write8] - - ;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR)); - ;mov edx, esi - ;add edx, VIA_REG_OFFSET_CURR_PTR - ;xor eax, eax - ;call [ctrl.ctrl_write8] - - ret -endp - - -align 4 -proc detect_controller - locals - last_bus dd ? - bus dd ? - devfn dd ? - endl - - xor eax, eax - mov [bus], eax - inc eax - call PciApi - cmp eax, -1 - je .err - - mov [last_bus], eax - -.next_bus: - and [devfn], 0 -.next_dev: - stdcall PciRead32, [bus], [devfn], dword 0 - test eax, eax - jz .next - cmp eax, -1 - je .next - - mov edi, devices -@@: - mov ebx, [edi] - test ebx, ebx - jz .next - - cmp eax, ebx - je .found - add edi, 12 - jmp @B -.next: - inc [devfn] - cmp [devfn], 256 - jb .next_dev - mov eax, [bus] - inc eax - mov [bus], eax - cmp eax, [last_bus] - jna .next_bus - xor eax, eax - ret -.found: - mov ebx, [bus] - mov [ctrl.bus], ebx - - mov ecx, [devfn] - mov [ctrl.devfn], ecx - - mov edx, eax - and edx, 0xFFFF - mov [ctrl.vendor], edx - shr eax, 16 - mov [ctrl.dev_id], eax - - mov ebx, [edi+4] - mov [ctrl.ctrl_ids], ebx - mov esi, [edi+8] - mov [ctrl.ctrl_setup], esi - - cmp edx, VID_VIA - jne @F - mov [ctrl.vendor_ids], msg_VIA - ret -@@: - -.err: - xor eax, eax - mov [ctrl.vendor_ids], eax ;something wrong ? - ret -endp - -align 4 -proc init_controller - - stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 - mov ebx, eax - and eax, 0xFFFF - mov [ctrl.pci_cmd], eax - shr ebx, 16 - mov [ctrl.pci_stat], ebx - - mov esi, msgPciCmd - call SysMsgBoardStr - call dword2str - call SysMsgBoardStr - - mov esi, msgPciStat - call SysMsgBoardStr - mov eax, [ctrl.pci_stat] - call dword2str - call SysMsgBoardStr - - mov esi, msgCtrlIsaIo - call SysMsgBoardStr - stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 - call dword2str - call SysMsgBoardStr - - and eax, 0xFFC0 - mov [ctrl.ctrl_io_base], eax - -.default: - stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C - and eax, 0xFF -@@: - mov [ctrl.int_line], eax - - ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42 - ;mov byte [old_legacy], al - - ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43 - ;mov byte [old_legacy_cfg], al - - ;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM - ;xor al, 0xFF - ;and al, byte [old_legacy] - ;and eax, 0xFF - ;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42 - ;mov byte [old_legacy], al - - call [ctrl.ctrl_setup] - xor eax, eax - inc eax - ret -endp - -align 4 -proc set_VIA - mov [ctrl.codec_read16], codec_io_r16 ;virtual - mov [ctrl.codec_write16], codec_io_w16 ;virtual - - mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual - mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual - mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual - - mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual - mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual - mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual - ret -endp - - -align 4 -proc init_codec - locals - counter dd ? - endl - - mov esi, msgControl - call SysMsgBoardStr - stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL - and eax, 0xFF - call dword2str - call SysMsgBoardStr - - mov esi, msgStatus - call SysMsgBoardStr - stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT - and eax, 0xFF - push eax - call dword2str - call SysMsgBoardStr - pop eax - - test eax, VIA_ACLINK_C00_READY - jz .ready - - call reset_codec - test eax, eax - jz .err - -.ready: - xor edx, edx ; ac_reg_0 - call [ctrl.codec_write16] - jmp .done - -.err: - xor eax, eax ; timeout error - ret - -.done: - call detect_codec - - xor eax, eax - inc eax - ret -endp - -align 4 -proc reset_codec - stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \ - VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC - mov eax, 100000 ; wait 100 ms - call StallExec -.cold: - call cold_reset - jnc .ok - - if DEBUG - mov esi, msgCFail - call SysMsgBoardStr - end if - xor eax, eax ; timeout error - ret -.ok: - if DEBUG - mov esi, msgResetOk - call SysMsgBoardStr - end if - xor eax, eax - inc eax - ret -endp - - -align 4 -proc cold_reset - locals - counter dd ? - endl - - stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0 - - if DEBUG - mov esi, msgCold - call SysMsgBoardStr - end if - - mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms - call StallExec - - ;; ACLink on, deassert ACLink reset, VSR, SGD data out - ;; note - FM data out has trouble with non VRA codecs !! - stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT - - mov [counter], 16 ; total 20*100 ms = 2s -.wait: - stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT - test eax, VIA_ACLINK_C00_READY - jnz .ok - - mov eax, 100000 ; wait 100 ms - call StallExec - - dec [counter] - jnz .wait - - if DEBUG - mov esi, msgCRFail - call SysMsgBoardStr - end if - -.fail: - stc - ret -.ok: - mov esi, msgControl - call SysMsgBoardStr - stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL - call dword2str - call SysMsgBoardStr - - mov esi, msgStatus - call SysMsgBoardStr - stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT - and eax, 0xFF - push eax - call dword2str - call SysMsgBoardStr - pop eax - - test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY - jz .fail - clc - ret -endp - -align 4 -play: - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX - mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000 - mov [ctrl.lvi_reg], 16 - call [ctrl.ctrl_write32] - - mov eax, VIA_REG_CTRL_INT - or eax, VIA_REG_CTRL_START - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL - call [ctrl.ctrl_write8] - - xor eax, eax - ret - -align 4 -stop: - mov eax, VIA_REG_CTRL_INT - or eax, VIA_REG_CTRL_TERMINATE - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL - call [ctrl.ctrl_write8] - - stdcall channel_reset, VIADEV_PLAYBACK - xor eax, eax - ret - -align 4 -proc get_dev_info stdcall, p_info:dword - virtual at esi - CTRL_INFO CTRL_INFO - end virtual - - mov esi, [p_info] - mov eax, [ctrl.int_line] - mov ecx, [ctrl.ctrl_io_base] - mov [CTRL_INFO.irq], eax - mov [CTRL_INFO.ctrl_io_base], ecx - - xor eax, eax - ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR - ;call [ctrl.ctrl_read32] - mov [CTRL_INFO.codec_io_base], eax - ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX - ;call [ctrl.ctrl_read32] - mov [CTRL_INFO.codec_mem_base], eax - ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT - ;call [ctrl.ctrl_read32] - mov [CTRL_INFO.ctrl_mem_base], eax - - mov eax, [codec.chip_id] - mov [CTRL_INFO.codec_id], eax - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL - call [ctrl.ctrl_read8] - and eax, 0xFF - mov [CTRL_INFO.glob_cntrl], eax - - mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS - call [ctrl.ctrl_read8] - and eax, 0xFF - mov [CTRL_INFO.glob_sta], eax - - mov ebx, [ctrl.pci_cmd] - mov [CTRL_INFO.pci_cmd], ebx - ret -endp - -align 4 -proc set_callback stdcall, handler:dword - mov eax, [handler] - mov [ctrl.user_callback], eax - ret -endp - - -align 4 -proc codec_check_ready stdcall - locals - counter dd ? - endl - - mov [counter], 1000 ; total 1000*1 ms = 1s -.wait: - call [ctrl.codec_read16] - test eax, VIA_REG_AC97_BUSY - jz .ok - - mov eax, 1000 ; wait 1 ms - call StallExec - - sub [counter] , 1 - jnz .wait -.err: - mov eax, -1 - ret -.ok: - and eax, 0xFFFF - ret -endp - - -align 4 -proc codec_valid stdcall - stdcall codec_check_ready - ret -endp - -align 4 -proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax - locals - counter dd ? - endl - - ;Use only primary codec. - mov eax, [ac_reg] - and eax, 0x7F - shl eax, VIA_REG_AC97_CMD_SHIFT - or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ - - mov [counter], 3 ; total 3*20 ms = 60ms -.wait: - push eax - call [ctrl.codec_write16] - - mov eax, 20000 ; wait 20 ms - call StallExec - - stdcall codec_valid, - cmp eax, 0 - pop eax - jge .ok - - sub [counter] , 1 - jnz .wait - jmp .err - -.ok: - mov eax, 25000 ; wait 25 ms - call StallExec - - call [ctrl.codec_read16] ;change edx !!! - and eax, 0xFFFF - ret -.err: - if DEBUG - mov esi, msgCInvalid - call SysMsgBoardStr - end if - mov eax, -1 ; invalid codec error - ret -endp - -align 4 -proc codec_write stdcall, ac_reg:dword - ;Use only primary codec. - mov esi, [ac_reg] - mov edx, esi - shl edx, VIA_REG_AC97_CMD_SHIFT - - shl eax, VIA_REG_AC97_DATA_SHIFT - or edx, eax - - mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY - shl eax, VIA_REG_AC97_CODEC_ID_SHIFT - or edx, eax - - mov eax, edx - mov edx, esi - call [ctrl.codec_write16] - mov [codec.regs+esi], ax - - stdcall codec_check_ready - cmp eax, 0 - jl .err -.ok: - ret -.err: - if DEBUG - mov esi, msgCFail - call SysMsgBoardStr - end if - ;mov eax, -1 ; codec not ready error - ret -endp - -align 4 -proc StallExec - push ecx - push edx - push ebx - push eax - - mov ecx, CPU_FREQ - mul ecx - mov ebx, eax ;low - mov ecx, edx ;high - rdtsc - add ebx, eax - adc ecx, edx -@@: - rdtsc - sub eax, ebx - sbb edx, ecx - js @B - - pop eax - pop ebx - pop edx - pop ecx - ret -endp - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; CONTROLLER IO functions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -align 4 -proc codec_io_r16 ;r32 - mov edx, [ctrl.ctrl_io_base] - add edx, VIA_REG_AC97 - in eax, dx - ret -endp - -align 4 -proc codec_io_w16 ;w32 - mov edx, [ctrl.ctrl_io_base] - add edx, VIA_REG_AC97 - out dx, eax - ret -endp - -align 4 -proc ctrl_io_r8 - add edx, [ctrl.ctrl_io_base] - in al, dx - ret -endp - -align 4 -proc ctrl_io_r16 - add edx, [ctrl.ctrl_io_base] - in ax, dx - ret -endp - -align 4 -proc ctrl_io_r32 - add edx, [ctrl.ctrl_io_base] - in eax, dx - ret -endp - -align 4 -proc ctrl_io_w8 - add edx, [ctrl.ctrl_io_base] - out dx, al - ret -endp - -align 4 -proc ctrl_io_w16 - add edx, [ctrl.ctrl_io_base] - out dx, ax - ret -endp - -align 4 -proc ctrl_io_w32 - add edx, [ctrl.ctrl_io_base] - out dx, eax - ret -endp - - -align 4 -dword2str: - push eax ebx ecx - mov esi, hex_buff - mov ecx, -8 - @@: - rol eax, 4 - mov ebx, eax - and ebx, 0x0F - mov bl, [ebx+hexletters] - mov [8+esi+ecx], bl - inc ecx - jnz @B - pop ecx ebx eax - ret - -hexletters db '0123456789ABCDEF' -hex_buff db 8 dup(0),13,10,0 - - -include "codec.inc" - -align 4 -devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA - dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA - dd 0 ;terminator - - -version dd (5 shl 16) or (API_VERSION and 0xFFFF) - -msg_VT82C686 db 'VT82C686', 13,10, 0 -msg_VT8233 db 'VT8233', 13,10, 0 -msg_VIA db 'VIA' , 13,10, 0 - -szKernel db 'KERNEL', 0 -sz_sound_srv db 'SOUND',0 - -msgInit db 'detect hardware...',13,10,0 -msgFail db 'device not found',13,10,0 -msgAttchIRQ db 'IRQ line not supported', 13,10, 0 -msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 -msgPlay db 'start play', 13,10,0 -msgStop db 'stop play', 13,10,0 -;msgIRQ db 'AC97 IRQ', 13,10,0 -;msgInitCtrl db 'init controller',13,10,0 -;msgInitCodec db 'init codec',13,10,0 -msgPrimBuff db 'create primary buffer ...',0 -msgDone db 'done',13,10,0 -msgRemap db 'Remap IRQ',13,10,0 -;msgReg db 'set service handler',13,10,0 -;msgOk db 'service installed',13,10,0 -msgCold db 'cold reset',13,10,0 -;msgWarm db 'warm reset',13,10,0 -;msgWRFail db 'warm reset failed',13,10,0 -msgCRFail db 'cold reset failed',13,10,0 -msgCFail db 'codec not ready',13,10,0 -msgCInvalid db 'codec is not valid',13,10,0 ;Asper -msgResetOk db 'reset complete',13,10,0 -msgStatus db 'global status ',0 -msgControl db 'global control ',0 -msgPciCmd db 'PCI command ',0 -msgPciStat db 'PCI status ',0 -msgCtrlIsaIo db 'controller io base ',0 -;msgMixIsaIo db 'codec io base ',0 -;msgCtrlMMIo db 'controller mmio base ',0 -;msgMixMMIo db 'codec mmio base ',0 -;msgIrqMap db 'AC97 irq map as ',0 - - -section '.data' data readable writable align 16 - -pcmout_bdl rq 32 -buff_list rd 32 - -codec CODEC -ctrl AC_CNTRL - +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +format MS COFF + +DEBUG equ 1 + +include 'proc32.inc' +include 'imports.inc' + +API_VERSION equ 0x01000100 + +USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices +IRQ_REMAP equ 0 +IRQ_LINE equ 0 + + +;irq 0,1,2,8,12,13 недоступны +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010100000b + +if USE_COM_IRQ +ATTCH_IRQ equ 0000111010111000b +end if + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT5 EQU 0x00000020 +BIT10 EQU 0x00000400 + +VID_VIA equ 0x1106 + +CTRL_VT82C686 equ 0x3058 +CTRL_VT8233_5 equ 0x3059 + + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume +CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate + + +;VIA host controller registers set +;; common offsets +VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status + VIA_REG_STAT_ACTIVE equ 0x80 ;; RO + VIA_REG_STAT_PAUSED equ 0x40 ;; RO + VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO + VIA_REG_STAT_STOPPED equ 0x04 ;; RWC + VIA_REG_STAT_EOL equ 0x02 ;; RWC + VIA_REG_STAT_FLAG equ 0x01 ;; RWC +VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control + VIA_REG_CTRL_START equ 0x80 ;; WO + VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO + VIA_REG_CTRL_AUTOSTART equ 0x20 + VIA_REG_CTRL_PAUSE equ 0x08 ;; RW + VIA_REG_CTRL_INT_STOP equ 0x04 + VIA_REG_CTRL_INT_EOL equ 0x02 + VIA_REG_CTRL_INT_FLAG equ 0x01 + VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented + VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \ + VIA_REG_CTRL_INT_EOL or \ + VIA_REG_CTRL_AUTOSTART) +VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only) + VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL + VIA_REG_TYPE_16BIT equ 0x20 ;; RW + VIA_REG_TYPE_STEREO equ 0x10 ;; RW + VIA_REG_TYPE_INT_LLINE equ 0x00 + VIA_REG_TYPE_INT_LSAMPLE equ 0x04 + VIA_REG_TYPE_INT_LESSONE equ 0x08 + VIA_REG_TYPE_INT_MASK equ 0x0c + VIA_REG_TYPE_INT_EOL equ 0x02 + VIA_REG_TYPE_INT_FLAG equ 0x01 +VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer +VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer +VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate + VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW + VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW +VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit) +VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only) + + +VIADEV_PLAYBACK equ 0x00 +VIADEV_CAPTURE equ 0x10 +VIADEV_FM equ 0x20 + +;; AC'97 ;; +VIA_REG_AC97 equ 0x80 ; dword + VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30) + VIA_REG_AC97_CODEC_ID_SHIFT equ 30 + VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00 + VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01 + VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27) + VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25) + VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24) + VIA_REG_AC97_READ equ 0x00800000 ;(1<<23) + VIA_REG_AC97_CMD_SHIFT equ 16 + VIA_REG_AC97_CMD_MASK equ 0x7E + VIA_REG_AC97_DATA_SHIFT equ 0 + VIA_REG_AC97_DATA_MASK equ 0xFFFF + +VIA_REG_SGD_SHADOW equ 0x84 ; dword + +;; via8233-specific registers ;; +VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte +VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte +VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels + VIA_REG_MULTPLAY_FMT_8BIT equ 0x00 + VIA_REG_MULTPLAY_FMT_16BIT equ 0x80 + VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6) +VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable + VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40 + +VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33 + +VIA_TBL_BIT_FLAG equ 0x40000000 +VIA_TBL_BIT_EOL equ 0x80000000 + +;; pci space ;; +VIA_ACLINK_STAT equ 0x40 + ;... + VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready +VIA_ACLINK_CTRL equ 0x41 + VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable + VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert + VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi + VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi + VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA + VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM + VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only + VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only + VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \ + VIA_ACLINK_CTRL_RESET or \ + VIA_ACLINK_CTRL_PCM or \ + VIA_ACLINK_CTRL_VRA) +VIA_FUNC_ENABLE equ 0x42 + VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet! + VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented! + VIA_FUNC_RX2C_WRITE equ 0x20 + VIA_FUNC_SB_FIFO_EMPTY equ 0x10 + VIA_FUNC_ENABLE_GAME equ 0x08 + VIA_FUNC_ENABLE_FM equ 0x04 + VIA_FUNC_ENABLE_MIDI equ 0x02 + VIA_FUNC_ENABLE_SB equ 0x01 +VIA_PNP_CONTROL equ 0x43 +VIA_FM_NMI_CTRL equ 0x48 +VIA8233_VOLCHG_CTRL equ 0x48 +VIA8233_SPDIF_CTRL equ 0x49 + VIA8233_SPDIF_DX3 equ 0x08 + VIA8233_SPDIF_SLOT_MASK equ 0x03 + VIA8233_SPDIF_SLOT_1011 equ 0x00 + VIA8233_SPDIF_SLOT_34 equ 0x01 + VIA8233_SPDIF_SLOT_78 equ 0x02 + VIA8233_SPDIF_SLOT_69 equ 0x03 +;] Asper + + +SRV_GETVERSION equ 0 +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + end if + + call init_controller + test eax, eax + jz .fail + + call init_codec + test eax, eax + jz .fail + + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + call create_primary_buff + mov esi, msgDone + call SysMsgBoardStr + + if IRQ_REMAP + pushf + cli + + mov ebx, [ctrl.int_line] + in al, 0xA1 + mov ah, al + in al, 0x21 + test ebx, ebx + jz .skip + bts ax, bx ;mask old line +.skip: + bts ax, IRQ_LINE ;mask new ine + out 0x21, al + mov al, ah + out 0xA1, al + + stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ + + mov dx, 0x4d0 ;8259 ELCR1 + in al, dx + bts ax, IRQ_LINE + out dx, al ;set level-triggered mode + mov [ctrl.int_line], IRQ_LINE + popf + mov esi, msgRemap + call SysMsgBoardStr + end if + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail_msg + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail_msg + + stdcall AttachIntHandler, ebx, ac97_irq_VIA, dword 0 +.reg: + stdcall RegService, sz_sound_srv, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax + ret +.fail_msg: + call SysMsgBoardStr + xor eax, eax + ret +.stop: + call stop + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + + cmp eax, SRV_GETVERSION + jne @F + mov eax, [edi+output] + cmp [edi+out_size], 4 + jne .fail + + mov [eax], dword API_VERSION + xor eax, eax + ret +@@: + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov eax, [edi+input] + mov eax, [eax] + call set_master_vol ;eax= vol + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + stdcall get_master_vol, ebx + ret +@@: + cmp eax, DEV_GET_INFO + jne @F + mov ebx, [edi+output] + stdcall get_dev_info, ebx + ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + + +align 4 +proc ac97_irq_VIA + locals + status db 0 + endl + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS + call [ctrl.ctrl_read8] + test al, VIA_REG_STAT_ACTIVE + jz @f + + and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED + mov byte [status], al + + mov ebx, dword [buff_list] + cmp [ctrl.user_callback], 0 + je @f + stdcall [ctrl.user_callback], ebx + @@: + mov al, byte [status] ;; ack ;; + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS + call [ctrl.ctrl_write8] + + ret +endp + + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + mov eax, [ctrl.buffer] + call GetPgAddr + mov edi, pcmout_bdl + stosd + mov eax, 0x80004000 + stosd + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + ;add eax, 0x4000 + add edi, 4 + loop @B + + stdcall channel_reset, VIADEV_PLAYBACK + stdcall codec_check_ready + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr + and ebx, 0xFFF + add eax, ebx + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR + call [ctrl.ctrl_write32] + + stdcall codec_check_ready + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L + mov eax, 7;31 + call [ctrl.ctrl_write8] + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R + mov eax, 7;31 + call [ctrl.ctrl_write8] + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX + mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000 + mov [ctrl.lvi_reg], 16;0xF;eax + call [ctrl.ctrl_write32] + + stdcall codec_check_ready + ret +endp + + +proc channel_reset channel:dword + mov esi, dword [channel] + mov edx, esi + add edx, VIA_REG_OFFSET_CONTROL + mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET + call [ctrl.ctrl_write8] + + mov edx, esi + add edx, VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_read8] + + mov eax, 50000 ; wait 50 ms + call StallExec + ; disable interrupts + mov edx, esi + add edx, VIA_REG_OFFSET_CONTROL + xor eax, eax + call [ctrl.ctrl_write8] + + ; clear interrupts + mov edx, esi + add edx, VIA_REG_OFFSET_STATUS + mov eax, 0x03 + call [ctrl.ctrl_write8] + + ;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */ + ; mov edx, esi ;; for via686 + ; add edx, VIA_REG_OFFSET_TYPE + ; mov eax, 0x03 + ; call [ctrl.ctrl_write8] + + ;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR)); + ;mov edx, esi + ;add edx, VIA_REG_OFFSET_CURR_PTR + ;xor eax, eax + ;call [ctrl.ctrl_write8] + + ret +endp + + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + cmp edx, VID_VIA + jne @F + mov [ctrl.vendor_ids], msg_VIA + ret +@@: + +.err: + xor eax, eax + mov [ctrl.vendor_ids], eax ;something wrong ? + ret +endp + +align 4 +proc init_controller + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + mov esi, msgPciCmd + call SysMsgBoardStr + call dword2str + call SysMsgBoardStr + + mov esi, msgPciStat + call SysMsgBoardStr + mov eax, [ctrl.pci_stat] + call dword2str + call SysMsgBoardStr + + mov esi, msgCtrlIsaIo + call SysMsgBoardStr + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + call dword2str + call SysMsgBoardStr + + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + +.default: + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF +@@: + mov [ctrl.int_line], eax + + ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42 + ;mov byte [old_legacy], al + + ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43 + ;mov byte [old_legacy_cfg], al + + ;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM + ;xor al, 0xFF + ;and al, byte [old_legacy] + ;and eax, 0xFF + ;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42 + ;mov byte [old_legacy], al + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_VIA + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL + and eax, 0xFF + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT + and eax, 0xFF + push eax + call dword2str + call SysMsgBoardStr + pop eax + + test eax, VIA_ACLINK_C00_READY + jz .ready + + call reset_codec + test eax, eax + jz .err + +.ready: + xor edx, edx ; ac_reg_0 + call [ctrl.codec_write16] + jmp .done + +.err: + xor eax, eax ; timeout error + ret + +.done: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \ + VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC + mov eax, 100000 ; wait 100 ms + call StallExec +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + if DEBUG + mov esi, msgResetOk + call SysMsgBoardStr + end if + xor eax, eax + inc eax + ret +endp + + +align 4 +proc cold_reset + locals + counter dd ? + endl + + stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0 + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms + call StallExec + + ;; ACLink on, deassert ACLink reset, VSR, SGD data out + ;; note - FM data out has trouble with non VRA codecs !! + stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT + + mov [counter], 16 ; total 20*100 ms = 2s +.wait: + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT + test eax, VIA_ACLINK_C00_READY + jnz .ok + + mov eax, 100000 ; wait 100 ms + call StallExec + + dec [counter] + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if + +.fail: + stc + ret +.ok: + mov esi, msgControl + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT + and eax, 0xFF + push eax + call dword2str + call SysMsgBoardStr + pop eax + + test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY + jz .fail + clc + ret +endp + +align 4 +play: + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX + mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000 + mov [ctrl.lvi_reg], 16 + call [ctrl.ctrl_write32] + + mov eax, VIA_REG_CTRL_INT + or eax, VIA_REG_CTRL_START + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_write8] + + xor eax, eax + ret + +align 4 +stop: + mov eax, VIA_REG_CTRL_INT + or eax, VIA_REG_CTRL_TERMINATE + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_write8] + + stdcall channel_reset, VIADEV_PLAYBACK + xor eax, eax + ret + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ecx, [ctrl.ctrl_io_base] + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.ctrl_io_base], ecx + + xor eax, eax + ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR + ;call [ctrl.ctrl_read32] + mov [CTRL_INFO.codec_io_base], eax + ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX + ;call [ctrl.ctrl_read32] + mov [CTRL_INFO.codec_mem_base], eax + ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT + ;call [ctrl.ctrl_read32] + mov [CTRL_INFO.ctrl_mem_base], eax + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_read8] + and eax, 0xFF + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS + call [ctrl.ctrl_read8] + and eax, 0xFF + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + + +align 4 +proc codec_check_ready stdcall + locals + counter dd ? + endl + + mov [counter], 1000 ; total 1000*1 ms = 1s +.wait: + call [ctrl.codec_read16] + test eax, VIA_REG_AC97_BUSY + jz .ok + + mov eax, 1000 ; wait 1 ms + call StallExec + + sub [counter] , 1 + jnz .wait +.err: + mov eax, -1 + ret +.ok: + and eax, 0xFFFF + ret +endp + + +align 4 +proc codec_valid stdcall + stdcall codec_check_ready + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + locals + counter dd ? + endl + + ;Use only primary codec. + mov eax, [ac_reg] + and eax, 0x7F + shl eax, VIA_REG_AC97_CMD_SHIFT + or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ + + mov [counter], 3 ; total 3*20 ms = 60ms +.wait: + push eax + call [ctrl.codec_write16] + + mov eax, 20000 ; wait 20 ms + call StallExec + + stdcall codec_valid, + cmp eax, 0 + pop eax + jge .ok + + sub [counter] , 1 + jnz .wait + jmp .err + +.ok: + mov eax, 25000 ; wait 25 ms + call StallExec + + call [ctrl.codec_read16] ;change edx !!! + and eax, 0xFFFF + ret +.err: + if DEBUG + mov esi, msgCInvalid + call SysMsgBoardStr + end if + mov eax, -1 ; invalid codec error + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + ;Use only primary codec. + mov esi, [ac_reg] + mov edx, esi + shl edx, VIA_REG_AC97_CMD_SHIFT + + shl eax, VIA_REG_AC97_DATA_SHIFT + or edx, eax + + mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY + shl eax, VIA_REG_AC97_CODEC_ID_SHIFT + or edx, eax + + mov eax, edx + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + + stdcall codec_check_ready + cmp eax, 0 + jl .err +.ok: + ret +.err: + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + ;mov eax, -1 ; codec not ready error + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx, edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + js @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 ;r32 + mov edx, [ctrl.ctrl_io_base] + add edx, VIA_REG_AC97 + in eax, dx + ret +endp + +align 4 +proc codec_io_w16 ;w32 + mov edx, [ctrl.ctrl_io_base] + add edx, VIA_REG_AC97 + out dx, eax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + + +align 4 +dword2str: + push eax ebx ecx + mov esi, hex_buff + mov ecx, -8 + @@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + pop ecx ebx eax + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +include "codec.inc" + +align 4 +devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA + dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA + dd 0 ;terminator + + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +msg_VT82C686 db 'VT82C686', 13,10, 0 +msg_VT8233 db 'VT8233', 13,10, 0 +msg_VIA db 'VIA' , 13,10, 0 + +szKernel db 'KERNEL', 0 +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +;msgIRQ db 'AC97 IRQ', 13,10,0 +;msgInitCtrl db 'init controller',13,10,0 +;msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer ...',0 +msgDone db 'done',13,10,0 +msgRemap db 'Remap IRQ',13,10,0 +;msgReg db 'set service handler',13,10,0 +;msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +;msgWarm db 'warm reset',13,10,0 +;msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgCInvalid db 'codec is not valid',13,10,0 ;Asper +msgResetOk db 'reset complete',13,10,0 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 +msgPciCmd db 'PCI command ',0 +msgPciStat db 'PCI status ',0 +msgCtrlIsaIo db 'controller io base ',0 +;msgMixIsaIo db 'codec io base ',0 +;msgCtrlMMIo db 'controller mmio base ',0 +;msgMixMMIo db 'codec mmio base ',0 +;msgIrqMap db 'AC97 irq map as ',0 + + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + chip_type rb 1 \ No newline at end of file