1281 lines
29 KiB
NASM
1281 lines
29 KiB
NASM
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|||
|
;; ;;
|
|||
|
;; 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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㯭<EFBFBD>
|
|||
|
; 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
|